diff --git a/.github/workflows/coding_style_checks.yml b/.github/workflows/coding_style_checks.yml index 7f91930..79c61c4 100644 --- a/.github/workflows/coding_style_checks.yml +++ b/.github/workflows/coding_style_checks.yml @@ -12,7 +12,7 @@ on: - main - develop pull_request: - + jobs: check_linting: name: Check linting using the reusable workflow diff --git a/.github/workflows/extra_checks.yml b/.github/workflows/extra_checks.yml index b90d19f..2c023e6 100644 --- a/.github/workflows/extra_checks.yml +++ b/.github/workflows/extra_checks.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout the repository uses: actions/checkout@v5 - + # Note: no need to install docker manually, because it's already installed, see # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md diff --git a/.github/workflows/guidelines_enforcer.yml b/.github/workflows/guidelines_enforcer.yml index b217d84..702c05f 100644 --- a/.github/workflows/guidelines_enforcer.yml +++ b/.github/workflows/guidelines_enforcer.yml @@ -11,6 +11,7 @@ name: Ensure compliance with Ledger guidelines permissions: actions: write contents: read + pull-requests: write on: workflow_dispatch: @@ -23,5 +24,10 @@ on: jobs: guidelines_enforcer: + # TODO: this is disabled because the app is still not in the ledger app database, + # so the "Check app_load_params" step fails. + # Once it's there, this must be re-enabled. + # See https://github.com/mintlayer/mintlayer-ledger-app/issues/20. + if: false name: Call Ledger guidelines_enforcer uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1 diff --git a/Cargo.lock b/Cargo.lock index 4f1a245..5d07645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,9 +118,9 @@ checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bitstream-io" @@ -220,6 +220,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "const-hex" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" +dependencies = [ + "cfg-if", + "cpufeatures", + "proptest", + "serde_core", +] + [[package]] name = "const-zero" version = "0.1.1" @@ -255,6 +267,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -477,12 +498,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "image" version = "0.25.8" @@ -599,25 +614,25 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "ledger_device_sdk" -version = "1.35.1" +version = "1.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fc7dea35e2d9d0a305fc9594539af5f510cd7c2d764f944542c4710731ae58" +checksum = "f21c105fccec785d1007a3fd5d86fdfe44eeb7283e28565584d315caea0cde4d" dependencies = [ "const-zero", "include_gif", "ledger_secure_sdk_sys", "num-traits", "numtoa", - "rand_core", + "rand_core 0.6.4", "serde_json", "zeroize", ] [[package]] name = "ledger_secure_sdk_sys" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58d50b8764859daf1b5176c5aad8ccc989494c16b08fa266e22c7907e60956e9" +checksum = "cd7424fb1da714f47453c65a58ca4144fa576e91563c860522b31db4c6868408" dependencies = [ "bindgen", "cc", @@ -707,7 +722,7 @@ dependencies = [ [[package]] name = "mintlayer-app" -version = "0.1.0" +version = "1.0.0" dependencies = [ "image", "ledger_device_sdk", @@ -716,16 +731,16 @@ dependencies = [ [[package]] name = "mintlayer-app-core" -version = "0.1.0" +version = "1.0.0" dependencies = [ "bech32", "chrono", - "hex", + "const-hex", "ledger_device_sdk", "ledger_secure_sdk_sys", "mintlayer-core-primitives", "mintlayer-messages", - "testmacro", + "test-utils", ] [[package]] @@ -741,12 +756,15 @@ dependencies = [ [[package]] name = "mintlayer-messages" -version = "0.1.0" +version = "1.0.0" dependencies = [ "derive_more", + "ledger_device_sdk", "mintlayer-core-primitives", + "num-traits", "num_enum", "parity-scale-codec", + "test-utils", ] [[package]] @@ -978,6 +996,20 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bitflags", + "num-traits", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift", + "unarray", +] + [[package]] name = "pxfm" version = "0.1.25" @@ -1024,8 +1056,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_core 0.9.5", ] [[package]] @@ -1035,7 +1076,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -1047,6 +1098,21 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + [[package]] name = "rav1e" version = "0.7.1" @@ -1073,8 +1139,8 @@ dependencies = [ "once_cell", "paste", "profiling", - "rand", - "rand_chacha", + "rand 0.8.6", + "rand_chacha 0.3.1", "simd_helpers", "system-deps", "thiserror", @@ -1325,6 +1391,14 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "test-utils" +version = "1.0.0" +dependencies = [ + "ledger_device_sdk", + "testmacro", +] + [[package]] name = "testmacro" version = "0.1.0" @@ -1403,6 +1477,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.18" diff --git a/Cargo.toml b/Cargo.toml index 6343154..b2ff483 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,28 +4,30 @@ version.workspace = true edition = "2021" [workspace] -members = ["crates/app-core", "crates/messages"] +members = ["crates/app-core", "crates/messages", "crates/test-utils"] resolver = "2" [workspace.package] -version = "0.1.0" +version = "1.0.0" [workspace.dependencies] bech32 = { version = "0.11", default-features = false } chrono = { version = "0.4", default-features = false } -derive_more = { version = "2.1.1", default-features = false } -hex = { version = "0.4.3", default-features = false } -image = "0.25.8" -ledger_device_sdk = "1.35.1" -ledger_secure_sdk_sys = "1.16.1" -num_enum = { version = "0.7.5", default-features = false } +const-hex = { version = "1.19", default-features = false } +derive_more = { version = "2.1", default-features = false } +image = "0.25" +ledger_device_sdk = "1.35" +ledger_secure_sdk_sys = "1.16" +num_enum = { version = "0.7", default-features = false } +num-traits = { version = "0.2", default-features = false } # Note: the testmacro crate is published by Ledger and its source code comes from the `testmacro` # dir inside the sdk repo, i.e. https://github.com/LedgerHQ/ledger-device-rust-sdk/tree/cad196841dbd72c037cfa01bec81a4a3ae57a04e/testmacro # (though the published version is a bit older). -testmacro = "0.1.0" +testmacro = "0.1" mintlayer-app-core = { path = "crates/app-core" } mintlayer-messages = { path = "crates/messages" } +test-utils = { path = "crates/test-utils" } [workspace.dependencies.parity-scale-codec] git = "https://github.com/paritytech/parity-scale-codec.git" @@ -53,7 +55,7 @@ mintlayer-app-core.workspace = true image.workspace = true [[bin]] -# Note: we only have this section to disable tests, but Cargo inists that "name" should also +# Note: we only have this section to disable tests, but Cargo insists that "name" should also # be specified. name = "mintlayer-app" # The app bin crate is a thin wrapper around `mintlayer-app-core` and it's not supposed to have @@ -68,16 +70,16 @@ path = ["44'/19788'", "44'/1'"] name = "Mintlayer" [package.metadata.ledger.nanox] -icon = "icons/mintlayer_14x14.gif" +icon = "media/icons/mintlayer_14x14.gif" [package.metadata.ledger.nanosplus] -icon = "icons/mintlayer_14x14.gif" +icon = "media/icons/mintlayer_14x14.gif" [package.metadata.ledger.stax] -icon = "icons/mintlayer_32x32.gif" +icon = "media/icons/mintlayer_32x32.gif" [package.metadata.ledger.flex] -icon = "icons/mintlayer_40x40.gif" +icon = "media/icons/mintlayer_40x40.gif" [package.metadata.ledger.apex_p] -icon = "icons/mintlayer_32x32.png" +icon = "media/icons/mintlayer_32x32.png" diff --git a/README.md b/README.md index 326d124..9878636 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,17 @@ ![Rule enforcer](https://github.com/mintlayer/mintlayer-ledger-app/actions/workflows/guidelines_enforcer.yml/badge.svg) ![Build and tests](https://github.com/mintlayer/mintlayer-ledger-app/actions/workflows/build_and_functional_tests.yml/badge.svg) -This is the Mintlayer Ledger application for the Ledger Nano X, S+, Stax, Flex and Nano Gen 5 devices. +This is the Mintlayer Ledger application for the Ledger Nano X, Nano S+, Stax, Flex and Nano Gen 5 devices. -:warning: Nano S is not supported +ℹ️ Nano Gen 5 is usually referred to by its codename, Apex P. + +⚠️ Nano S is not supported. ## Quick start guide ### With VS Code -You can quickly setup a development environment on any platform (macOS, Linux or Windows) to build and test your application with [Ledger's VS Code extension](https://marketplace.visualstudio.com/items?itemName=LedgerHQ.ledger-dev-tools). +You can quickly set up a development environment on any platform (macOS, Linux or Windows) to build and test your application with [Ledger's VS Code extension](https://marketplace.visualstudio.com/items?itemName=LedgerHQ.ledger-dev-tools). By using Ledger's own developer tools [Docker image](https://github.com/LedgerHQ/ledger-app-builder/pkgs/container/ledger-app-builder%2Fledger-app-dev-tools), the extension allows you to **build** your apps with the latest SDK, **test** them on **Speculos** and **load** them on any supported device. @@ -19,27 +21,27 @@ By using Ledger's own developer tools [Docker image](https://github.com/LedgerHQ - On Ubuntu Linux, it should be running by default. - On macOS, install and launch [XQuartz](https://www.xquartz.org/) (make sure to go to XQuartz > Preferences > Security and check "Allow client connections"). - On Windows, install and launch [VcXsrv](https://sourceforge.net/projects/vcxsrv/) (make sure to configure it to disable access control). -- Install [VScode](https://code.visualstudio.com/download) and add [Ledger's extension](https://marketplace.visualstudio.com/items?itemName=LedgerHQ.ledger-dev-tools). -- Open a terminal and clone `app-boilerplate-rust` with `git clone git@github.com:LedgerHQ/app-boilerplate-rust.git`. -- Open the `app-boilerplate-rust` folder with VSCode. +- Install [VS Code](https://code.visualstudio.com/download) and add [Ledger's extension](https://marketplace.visualstudio.com/items?itemName=LedgerHQ.ledger-dev-tools). +- Open a terminal and clone `mintlayer-ledger-app` with `git clone git@github.com:mintlayer/mintlayer-ledger-app.git`. +- Open the `mintlayer-ledger-app` folder with VS Code. - Use Ledger extension's sidebar menu or open the tasks menu with `ctrl + shift + b` (`command + shift + b` on a Mac) to conveniently execute actions : - **Build** the app for the device model of your choice with `Build`. - **Test** your binary on the [Speculos emulator](https://github.com/LedgerHQ/speculos) with `Run with emulator`. - You can also **run functional tests**, load the app on a physical device, and more. -ℹ️ The terminal tab of VSCode will show you what commands the extension runs behind the scene. +ℹ️ The terminal tab of VS Code will show you what commands the extension runs behind the scene. ## With a terminal ### Prerequisites -If you do not wish to use the [VS Code extension](#with-vs-code), you can follow the following steps to setup a development environment on Linux, Windows or MacOS. +If you do not wish to use the [VS Code extension](#with-vs-code), you can follow the following steps to set up a development environment on Linux, Windows or macOS. - The [ledger-app-dev-tools](https://github.com/LedgerHQ/ledger-app-builder/pkgs/container/ledger-app-builder%2Fledger-app-dev-tools) Docker image contains all the required tools and libraries to build, test and load an application on a device. You can download it from the ghcr.io docker repository: -```shell -sudo docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest -``` + ```bash + docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest + ``` - Make sure you have an X11 server running : - On Ubuntu Linux, it should be running by default. @@ -47,17 +49,17 @@ sudo docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest - On Windows, install and launch [VcXsrv](https://sourceforge.net/projects/vcxsrv/) (make sure to configure it to disable access control). - You can then enter into this development environment by executing the following command from the directory of the application (`git` repository): - Linux (Ubuntu): - ```shell - sudo docker run --rm -ti --privileged -v "/dev/bus/usb:/dev/bus/usb" -v "$(realpath .):/app" --publish 5001:5001 --publish 9999:9999 -e DISPLAY=$DISPLAY -v '/tmp/.X11-unix:/tmp/.X11-unix' ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest - ``` + ```bash + docker run --user "$(id -u)":"$(id -g)" --rm -ti --privileged -v "/dev/bus/usb:/dev/bus/usb" -v "$(realpath .):/app" --publish 5000:5000 --publish 9999:9999 -e DISPLAY=$DISPLAY -v '/tmp/.X11-unix:/tmp/.X11-unix' ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest + ``` - macOS: - ```shell - sudo docker run --rm -ti --privileged -v "$(pwd -P):/app" --publish 5001:5001 --publish 9999:9999 -e DISPLAY='host.docker.internal:0' -v '/tmp/.X11-unix:/tmp/.X11-unix' ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest - ``` + ```bash + docker run --user "$(id -u)":"$(id -g)" --rm -ti --privileged -v "$(pwd -P):/app" --publish 5000:5000 --publish 9999:9999 -e DISPLAY='host.docker.internal:0' -v '/tmp/.X11-unix:/tmp/.X11-unix' ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest + ``` - Windows (with PowerShell): - ```shell - docker run --rm -ti --privileged -v "$(Get-Location):/app" -e DISPLAY='host.docker.internal:0' --publish 5001:5001 --publish 9999:9999 ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest - ``` + ```bash + docker run --rm -ti --privileged -v "$(Get-Location):/app" -e DISPLAY='host.docker.internal:0' --publish 5000:5000 --publish 9999:9999 ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest + ``` The application's code will be available from inside the docker container, you can proceed to the following compilation steps to build your app. @@ -69,7 +71,7 @@ You can build the Mintlayer app with the following command executed in the root cargo ledger build nanox ``` -This command will build the app for the Nano X, but you can use any supported device (`nanox`, `nanosplus`, `stax`, `flex`) +This command will build the app for the Nano X, but you can use any supported device (`nanox`, `nanosplus`, `stax`, `flex`, `apex_p`). ### Testing @@ -79,15 +81,17 @@ This Mintlayer app comes with functional tests implemented with Ledger's [Ragger - Install the tests requirements -```bash -pip install -r tests/requirements.txt -``` + ```bash + pip install -r tests/requirements.txt + ``` - Run the functional tests : -```shell -pytest tests/ --tb=short -v --device {nanosp | nanox | stax | flex} -``` + ```bash + pytest tests/ --tb=short -v --device {nanosp | nanox | stax | flex | apex_p} + ``` + +ℹ️ Speculos uses `nanosp` for Nano S+ (whereas `ledger_app.toml` lists it as `nanos+`). #### Emulator @@ -99,17 +103,15 @@ You can also run the app directly on the [Speculos emulator](https://github.com/ speculos --apdu-port 9999 --api-port 5000 --display headless --model nanosp target/nanosplus/release/mintlayer-app ``` -:warning: UI is displayed on `localhost:5000` +⚠️ UI is displayed on `localhost:5000`. -#### Stax or Flex +#### Stax, Flex or Nano Gen 5 ```bash speculos --apdu-port 9999 --api-port 5000 --model stax target/stax/release/mintlayer-app ``` -You can also specify the seed phrase with -s "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" - -:warning: UI is displayed by your X server +⚠️ UI is displayed by your X server. You can then send APDU using `ledgercomm` (`pip install ledgercomm`): @@ -117,33 +119,67 @@ You can then send APDU using `ledgercomm` (`pip install ledgercomm`): ledgercomm-send file test.apdu ``` +ℹ️ You can also specify the seed phrase via `-s`, e.g.: `-s "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"`. + ### Loading on device -:warning: Loading the built application on a device shall be performed out of the Docker container, by using [ledgerctl](https://github.com/LedgerHQ/ledgerctl): +On Linux, loading the application on a device can be done inside the docker container via: -```shell -pip3 install ledgerwallet +```bash +cargo ledger build nanox --load ``` +(the `--privileged -v "/dev/bus/usb:/dev/bus/usb"` part of the Docker run command line allows this). + +It can also be done outside the docker container on all platforms via [ledgerblue](https://pypi.org/project/ledgerblue/): + +* Install `ledgerblue`: + ```bash + pip install ledgerblue + ``` + +* Build the app inside the docker container as usual. + +* Load the app on device, e.g. for Flex: + ```bash + python -m ledgerblue.runScript --targetId --fileName target/flex/release/mintlayer-app.apdu --apdu --scp + ``` ℹ️ Your device must be connected, unlocked and the screen showing the dashboard (not inside an application). -For instance, for Flex: +#### About the device target ID +ledgerblue needs the device's `targetId`. + +If you call ledgerblue manually, note that its `--targetId` defaults to `0x31100002` (Nano S) — wrong for every other device, +and it is **not** auto-detected from the connected device. +The cleanest option is to let ledgerblue read the id straight from the ELF with `--elfFile`, which overrides `--targetId`: + +```bash +python -m ledgerblue.runScript --elfFile target/flex/release/mintlayer-app --fileName target/flex/release/mintlayer-app.apdu --apdu --scp +``` + +If you instead need the raw target ID value (e.g. for a CI script), the [`tools/get_target_id.py`](tools/get_target_id.py) +helper extracts it from the `ledger.target_id` ELF section: ```bash -ledgerctl install -f target/flex/release/app_flex.json +python tools/get_target_id.py target/flex/release/mintlayer-app # -> 0x33300004 ``` ## Continuous Integration The following workflows are executed in [GitHub Actions](https://github.com/features/actions) : -- Ledger guidelines enforcer which verifies that an app is compliant with Ledger guidelines. The successful completion of this reusable workflow is a mandatory step for an app to be available on the Ledger application store. More information on the guidelines can be found in the repository [ledger-app-workflow](https://github.com/LedgerHQ/ledger-app-workflows) -- Compilation of the application for all supported devices in the [ledger-app-builder](https://github.com/LedgerHQ/ledger-app-builder) docker image -- End-to-end tests with the [Speculos](https://github.com/LedgerHQ/speculos) emulator and [ragger](https://github.com/LedgerHQ/ragger) (see [tests/](tests/)) -- Various lint checks : - - Source code lint checks with `cargo fmt` - - Python functional test code lint checks with `pylint` and `mypy` +- Ledger guidelines enforcer which verifies that an app is compliant with Ledger guidelines. The successful completion of this reusable workflow is a mandatory step for an app to be available on the Ledger application store. More information on the guidelines can be found in the repository [ledger-app-workflow](https://github.com/LedgerHQ/ledger-app-workflows). +- Compilation of the application for all supported devices in the [ledger-app-builder](https://github.com/LedgerHQ/ledger-app-builder) docker image. +- End-to-end tests with the [Speculos](https://github.com/LedgerHQ/speculos) emulator and [ragger](https://github.com/LedgerHQ/ragger) (see [tests/](tests/)). +- Various lint checks performed by Ledger's reusable workflows: + - Source code lint checks with `cargo fmt`. + - Python functional test code lint checks with `pylint` and `mypy`. +- Additional custom checks, run via `run_extra_checks.sh`. +- Unit tests, run via `run_unit_tests.sh`. ## Additional documentation -For development guidelines related to the app's memory usage see [docs/memory_usage.md](docs/memory_usage.md). +For the additional documentation, see the [docs](docs/) folder. + +- [docs/memory_usage.md](docs/memory_usage.md) - guidelines related to the app's memory usage. +- [docs/technical_specification.md](docs/technical_specification.md) - app's technical specification. diff --git a/build.rs b/build.rs index 25e883c..0b997fb 100644 --- a/build.rs +++ b/build.rs @@ -1,19 +1,42 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2023 Ledger SAS. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + use std::process::Command; use image::{ImageFormat, ImageReader, Pixel}; +// TODO: all image files currently contain the Rust logo; need to replace them with Mintlayer logo. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/10. + fn main() { println!("cargo:rerun-if-changed=script.ld"); - println!("cargo:rerun-if-changed=icons/mintlayer_14x14.gif"); - println!("cargo:rerun-if-changed=icons/mask_14x14.gif"); + println!("cargo:rerun-if-changed=media/icons/mintlayer_14x14.gif"); + println!("cargo:rerun-if-changed=media/icons/mask_14x14.gif"); - let path = std::path::PathBuf::from("icons"); - let reader = ImageReader::open(path.join("mintlayer_14x14.gif")).unwrap(); - let img = reader.decode().unwrap(); - let mut gray = img.into_luma8(); + let icons_path = std::path::PathBuf::from("media/icons"); + let mut gray = ImageReader::open(icons_path.join("mintlayer_14x14.gif")) + .unwrap() + .decode() + .unwrap() + .into_luma8(); // Apply mask - let mask = ImageReader::open(path.join("mask_14x14.gif")) + let mask = ImageReader::open(icons_path.join("mask_14x14.gif")) .unwrap() .decode() .unwrap() @@ -30,7 +53,7 @@ fn main() { gray.put_pixel(x, y, gray_pixel); } - let glyph_path = std::path::PathBuf::from("glyphs"); + let glyph_path = std::path::PathBuf::from("media/glyphs"); gray.save_with_format(glyph_path.join("home_nano_nbgl.png"), ImageFormat::Png) .unwrap(); @@ -42,6 +65,9 @@ fn main() { let git_hash = String::from_utf8(output.stdout).expect("Failed to convert git output to UTF-8"); // Expose the Git hash as an environment variable + // TODO: this is unused. Either implement a custom command that would return this info + // (e.g. in the form of a full semantic version), or remove this. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/11. println!("cargo:rustc-env=GIT_HASH={}", git_hash.trim()); // Rerun the build script if .git/HEAD changes diff --git a/crates/app-core/Cargo.toml b/crates/app-core/Cargo.toml index 024e4ca..44b98f2 100644 --- a/crates/app-core/Cargo.toml +++ b/crates/app-core/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "mintlayer-app-core" version.workspace = true -edition = "2021" +edition = "2024" [dependencies] bech32 = { workspace = true, default-features = false, features = ["alloc"] } chrono = { workspace = true, default-features = false, features = ["alloc"] } -hex = { workspace = true, default-features = false, features = ["alloc"] } +const-hex = { workspace = true, default-features = false, features = ["alloc"] } ledger_device_sdk.workspace = true ledger_secure_sdk_sys.workspace = true mintlayer-core-primitives.workspace = true + mintlayer-messages.workspace = true [dev-dependencies] -ledger_device_sdk = { workspace = true, features = ["unit_test"] } -testmacro.workspace = true +test-utils.workspace = true [features] default = ["ledger_device_sdk/nano_nbgl"] diff --git a/crates/app-core/src/app_ui/address.rs b/crates/app-core/src/app_ui/address.rs index daaa282..2eb2577 100644 --- a/crates/app-core/src/app_ui/address.rs +++ b/crates/app-core/src/app_ui/address.rs @@ -1,7 +1,7 @@ /***************************************************************************** * Mintlayer Ledger App. * (c) 2023 Ledger SAS. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,22 @@ * limitations under the License. *****************************************************************************/ -use crate::{ - app_ui::utils::{compress_public_key, load_glyph, to_address}, - StatusWord, -}; -use mintlayer_messages::mlcp::{CoinType, Destination, PublicKey}; - use ledger_device_sdk::{ ecc::ECPublicKey, nbgl::{NbglAddressReview, NbglGlyph}, }; +use mintlayer_messages::{Destination, PublicKey}; + +use crate::{ + StatusWord, + app_ui::utils::{compress_public_key, load_glyph, to_address}, + mlcp, +}; + pub fn ui_display_pk( public_key: &ECPublicKey<65, T>, - coin_type: CoinType, + coin_type: mlcp::CoinType, ) -> Result { let pk = compress_public_key(public_key)?; diff --git a/crates/app-core/src/app_ui/menu.rs b/crates/app-core/src/app_ui/menu.rs index b6dff58..783f649 100644 --- a/crates/app-core/src/app_ui/menu.rs +++ b/crates/app-core/src/app_ui/menu.rs @@ -1,7 +1,7 @@ /***************************************************************************** * Mintlayer Ledger App. * (c) 2023 Ledger SAS. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/crates/app-core/src/app_ui/mod.rs b/crates/app-core/src/app_ui/mod.rs new file mode 100644 index 0000000..3763f0a --- /dev/null +++ b/crates/app-core/src/app_ui/mod.rs @@ -0,0 +1,21 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +pub mod address; +pub mod menu; +pub mod sign; +pub mod utils; diff --git a/crates/app-core/src/app_ui/sign.rs b/crates/app-core/src/app_ui/sign.rs index 4222b50..633efdb 100644 --- a/crates/app-core/src/app_ui/sign.rs +++ b/crates/app-core/src/app_ui/sign.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,28 +15,10 @@ * limitations under the License. *****************************************************************************/ -use alloc::string::String; -use alloc::{format, string::ToString}; +use alloc::{format, string::String, string::ToString}; +use chrono::{TimeZone, Utc}; use core::fmt::Write; -use crate::{ - app_ui::utils::{ - bech32m_encode, compress_public_key, load_glyph, to_address, to_public_key_hash, - }, - handlers::sign_tx::{CoinOrTokenId, InputCommand, TxParsingOutputsContext, TxType}, - StatusWord, -}; -use mintlayer_messages::{ - encode, - mlcp::{ - AccountCommand, AccountSpending, Amount, CoinType, Destination, IsTokenFreezable, - IsTokenUnfreezable, NftIssuance, OrderAccountCommand, OutputTimeLock, OutputValue, - PublicKey, TokenIssuance, TokenTotalSupply, TxOutput, VrfPublicKey, H256, - }, - AddrType, -}; - -use chrono::{TimeZone, Utc}; use ledger_device_sdk::{ ecc::ECPublicKey, nbgl::{ @@ -45,7 +27,24 @@ use ledger_device_sdk::{ }, }; -struct FormatedOutput { +use mintlayer_messages::{ + AccountCommand, AccountSpending, AddrType, Amount, DelegationId, Destination, H256, + IsTokenFreezable, IsTokenUnfreezable, NftIssuance, OrderAccountCommand, OrderId, + OutputTimeLock, OutputValue, PoolId, PublicKey, TokenId, TokenIssuance, TokenTotalSupply, + TxOutput, VrfPublicKey, encode, +}; + +use crate::{ + StatusWord, + app_ui::utils::{ + bech32m_encode, compress_public_key, load_glyph, to_address, to_public_key_hash, + }, + handlers::sign_tx::{CoinOrTokenId, InputCommand, TxSummaryCollector, TxType}, + mlcp, + utils::{make_displayable, make_displayable_str, output_value_with_amount}, +}; + +struct FormattedOutput { name: &'static str, value: String, } @@ -65,7 +64,7 @@ pub fn ui_start_streaming_review(review: &NbglStreamingReview) -> bool { pub fn ui_streaming_review_show_input( review: &NbglStreamingReview, input: &InputCommand, - coin: CoinType, + coin: mlcp::CoinType, ) -> Result { let input = format_input(input, coin)?; @@ -85,7 +84,7 @@ pub fn ui_streaming_review_show_input( pub fn ui_streaming_review_show_output( review: &NbglStreamingReview, output: &TxOutput, - coin: CoinType, + coin: mlcp::CoinType, ) -> Result { let output = format_output(output, coin)?; @@ -104,10 +103,10 @@ pub fn ui_streaming_review_show_output( pub fn ui_approve_streaming_review( review: &NbglStreamingReview, - ctx: &TxParsingOutputsContext, + tx_summary: &TxSummaryCollector, + coin: mlcp::CoinType, ) -> Result { - let coin = ctx.coin(); - let fees = ctx.summary().fees_iter().try_fold( + let fees = tx_summary.fees_iter().try_fold( String::new(), |mut acc, res| -> Result<_, StatusWord> { let (coin_or_token, fee) = res?; @@ -115,9 +114,8 @@ pub fn ui_approve_streaming_review( match coin_or_token { CoinOrTokenId::Coin => writeln!( acc, - "{} {}", - format_amount(Amount::from_atoms(fee), coin), - coin.coin_ticker() + "{}", + format_coin_amount_with_name(Amount::from_atoms(fee), coin), ) .map_err(|_| StatusWord::TxDisplayFail)?, @@ -125,10 +123,10 @@ pub fn ui_approve_streaming_review( if fee != 0 { writeln!( acc, - "{fee} {}", - id_to_address(token_id, coin.token_id_address_prefix())? + "{}", + format_token_amount_with_name(token_id, Amount::from_atoms(fee), coin)?, ) - .map_err(|_| StatusWord::TxDisplayFail)? + .map_err(|_| StatusWord::TxDisplayFail)?; } } }; @@ -147,7 +145,7 @@ pub fn ui_approve_streaming_review( NbglStreamingReviewStatus::Next | NbglStreamingReviewStatus::Skipped => {} }; - let title = transaction_title(&ctx.summary().tx_type()); + let title = transaction_title(&tx_summary.tx_type()); Ok(review.finish(title)) } @@ -158,8 +156,8 @@ fn transaction_title(tx_type: &Option) -> &'static str { Some(TxType::Burn) => "Sign burn transaction", Some(TxType::Htlc) => "Sign create HTLC transaction", Some(TxType::CreateDelegation) => "Sign create delegation transaction", - Some(TxType::DelegationStake) => "Sign stake delegation transaction", - Some(TxType::DelegationWithdrawal) => "Sign withdrawal delegation transaction", + Some(TxType::DelegateStaking) => "Sign delegate staking transaction", + Some(TxType::DelegationWithdrawal) => "Sign delegation withdrawal transaction", Some(TxType::CreateStakePool) => "Sign create stake pool transaction", Some(TxType::DecommissionStakePool) => "Sign decommission stake pool transaction", Some(TxType::CreateNft) => "Sign create NFT transaction", @@ -186,17 +184,20 @@ fn transaction_title(tx_type: &Option) -> &'static str { /// /// # Arguments /// -/// * `message` - A byte slice (`&[u8]`) containing the message to be signed. +/// * `message` - The message to be signed. +/// * `public_key` - The public key corresponding to the private key that will be used for signing. +/// * `coin_type` - The coin type (mainnet, testnet etc). +/// * `addr_type` - The address type (pk or pkh); this determines how `public_key` will be displayed. /// /// # Returns /// /// * `Ok(true)` if the user approves the signing. /// * `Ok(false)` if the user rejects. -/// * `Err(AppSW)` on error. +/// * `Err(StatusWord)` on error. pub fn ui_display_message( message: &[u8], public_key: &ECPublicKey<65, T>, - coin_type: CoinType, + coin_type: mlcp::CoinType, addr_type: AddrType, ) -> Result { let pk = compress_public_key(public_key)?; @@ -207,10 +208,7 @@ pub fn ui_display_message( }; let addr = to_address(&dest, coin_type)?; - let message_str = match core::str::from_utf8(message) { - Ok(s) if s.bytes().all(|b| (0x20..=0x7E).contains(&b)) => s.to_string(), - Ok(_) | Err(_) => format!("0x{}", hex::encode(message)), - }; + let message_str = make_displayable_str(message); let msg_fields = [ Field { @@ -219,7 +217,7 @@ pub fn ui_display_message( }, Field { name: "Message", - value: message_str.as_str(), + value: &message_str, }, ]; @@ -228,9 +226,13 @@ pub fn ui_display_message( // Create the NBGL review flow with titles appropriate for message signing. let review: NbglReview = NbglReview::new() .titles( - "Review message", // Initial title - "Cannot be undone", // Warning on the second screen - "Sign message", // Final confirmation prompt + // Title + "Review message", + // Subtitle; if non-empty, this will be shown on the second screen on nano devices + // and below the title on the first screen on touch devices. + "", + // Final confirmation prompt + "Sign message", ) .tx_type(TransactionType::Message) .glyph(&MINTLAYER); @@ -239,7 +241,7 @@ pub fn ui_display_message( Ok(review.show(&msg_fields)) } -fn vrf_to_address(key: &VrfPublicKey, coin: CoinType) -> Result { +fn vrf_to_address(key: &VrfPublicKey, coin: mlcp::CoinType) -> Result { bech32m_encode(coin.vrf_public_key_address_prefix(), &encode(key)) } @@ -247,7 +249,24 @@ fn id_to_address(id: &H256, hrp: &str) -> Result { bech32m_encode(hrp, &id.0) } -fn format_amount(amount: Amount, coin: CoinType) -> String { +fn token_id_to_address(id: &TokenId, coin: mlcp::CoinType) -> Result { + id_to_address(id.hash(), coin.token_id_address_prefix()) +} + +fn pool_id_to_address(id: &PoolId, coin: mlcp::CoinType) -> Result { + id_to_address(id.hash(), coin.pool_id_address_prefix()) +} + +fn delegation_id_to_address(id: &DelegationId, coin: mlcp::CoinType) -> Result { + id_to_address(id.hash(), coin.delegation_id_address_prefix()) +} + +fn order_id_to_address(id: &OrderId, coin: mlcp::CoinType) -> Result { + id_to_address(id.hash(), coin.order_id_address_prefix()) +} + +/// Format a coin amount as a decimal string. +fn format_coin_amount(amount: Amount, coin: mlcp::CoinType) -> String { let decimals = coin.coin_decimals() as usize; let mantissa = amount.into_atoms(); @@ -259,18 +278,35 @@ fn format_amount(amount: Amount, coin: CoinType) -> String { buffer } +/// Same as format_coin_amount, but also append the coin ticker to the amount. +fn format_coin_amount_with_name(amount: Amount, coin: mlcp::CoinType) -> String { + let mut amount = format_coin_amount(amount, coin); + amount.push(' '); + amount.push_str(coin.coin_ticker()); + amount +} + +fn format_token_amount_with_name( + token_id: &TokenId, + amount: Amount, + coin: mlcp::CoinType, +) -> Result { + let atoms = amount.into_atoms(); + let id_str = id_to_address(token_id.hash(), coin.token_id_address_prefix())?; + + Ok(format!("{atoms} atoms of {id_str}")) +} + fn format_atoms(amount: Amount) -> String { - amount.into_atoms().to_string() + format!("{} atoms", amount.into_atoms()) } -fn format_value(value: &OutputValue, coin: CoinType) -> Result { +fn format_value(value: &OutputValue, coin: mlcp::CoinType) -> Result { match value { - OutputValue::Coin(amount) => Ok(format!("Coins: {}", format_amount(*amount, coin))), - OutputValue::TokenV1(token_id, amount) => Ok(format!( - "Token: {} {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, - format_atoms(*amount) - )), + OutputValue::Coin(amount) => Ok(format_coin_amount_with_name(*amount, coin)), + OutputValue::TokenV1(token_id, amount) => { + format_token_amount_with_name(token_id, *amount, coin) + } } } @@ -289,22 +325,30 @@ fn format_timestamp(seconds_u64: u64) -> Result { fn format_lock(lock: &OutputTimeLock) -> Result { let s = match lock { OutputTimeLock::UntilHeight(h) => format!("Lock until block height {}", h.0), - OutputTimeLock::UntilTime(t) => format!("Lock until {}", format_timestamp(t.0 .0)?), + OutputTimeLock::UntilTime(t) => format!("Lock until {}", format_timestamp(t.0.0)?), OutputTimeLock::ForBlockCount(b) => format!("Lock for {} blocks", b.0), OutputTimeLock::ForSeconds(s) => format!("Lock for {} seconds", s.0), }; Ok(s) } -/// Formats a transaction output into a FormatedOutput. +/// Formats a transaction output into a FormattedOutput. /// /// # Arguments /// * `output` - A reference to the `TxOutput` enum variant to format. -/// * `coin` - The coin information, used for formatting amounts. +/// * `coin` - The coin type (mainnet, testnet etc). /// /// # Returns -/// A FormatedOutput containing the title and value of the output. -fn format_output(output: &TxOutput, coin: CoinType) -> Result { +/// A FormattedOutput containing the title and value of the output. +fn format_output(output: &TxOutput, coin: mlcp::CoinType) -> Result { + // Note: on nanox and nanosp the screen space is very limited. Moreover, if the name part of + // a field doesn't fit into one line, it will be shrunk instead of being wrapped to the next + // line, which will make it incomprehensible. + // The limit is about 11-12 characters (e.g. "Chg token auth" is already too long and becomes + // "Chg to...th"). + // So, choose names carefully and always check the screen snapshots after they're regenerated. + // Same for inputs. + let (name, value) = match output { TxOutput::Transfer(value, destination) => ( "Transfer", @@ -333,10 +377,22 @@ fn format_output(output: &TxOutput, coin: CoinType) -> Result { let address_short = format!( - "Pool ID: {}\nStaker key: {}\nDecommission key: {}\nVRF public key: {}\nMargin ratio per thousand: {}\nCost per block: {}\nPledge{}\n", - id_to_address(pool_id.hash(), coin.pool_id_address_prefix())?, to_address(&data.staker, coin)?, to_address(&data.decommission_key, coin)?, vrf_to_address(&data.vrf_public_key, coin)?, data.margin_ratio_per_thousand.0, format_amount(data.cost_per_block, coin), - format_amount(data.pledge, coin)); - ("Create staking pool", address_short) + "Pool ID: {}\nStaker key: {}\nDecommission key: {}\nVRF public key: {}\nMargin ratio per thousand: {}\nCost per block: {}\nPledge: {}\n", + pool_id_to_address(pool_id, coin)?, + to_address(&data.staker, coin)?, + to_address(&data.decommission_key, coin)?, + vrf_to_address(&data.vrf_public_key, coin)?, + data.margin_ratio_per_thousand.0, + format_coin_amount_with_name(data.cost_per_block, coin), + format_coin_amount_with_name(data.pledge, coin) + ); + + let name = if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { + "Create pool" + } else { + "Create staking pool" + }; + (name, address_short) } TxOutput::ProduceBlockFromStake(destination, _pool_id) => { @@ -355,7 +411,7 @@ fn format_output(output: &TxOutput, coin: CoinType) -> Result Result Result { let TokenIssuance::V1(data) = x; - let ticker = String::from_utf8_lossy(data.token_ticker.as_ref()); - let metadata_uri = String::from_utf8_lossy(data.metadata_uri.as_ref()); + // Note: currently the consensus rules require that a token ticker can only be + // ascii alphanumeric, so we could just reject non-ascii tickers here. + // We use `make_displayable` here for simplicity and consistency. + let ticker = make_displayable(&data.token_ticker); + // Note: a metadata URI is allowed to have non-ascii chars, so `make_displayable` + // is not redundant here. + let metadata_uri = make_displayable(&data.metadata_uri); let total_supply_str = match data.total_supply { TokenTotalSupply::Unlimited => "UNLIMITED".to_string(), TokenTotalSupply::Lockable => "LOCKABLE".to_string(), TokenTotalSupply::Fixed(amount) => { - let formatted_amount = format_amount(amount, coin); + let formatted_amount = format_atoms(amount); format!("FIXED {}", formatted_amount) } }; @@ -404,7 +465,12 @@ fn format_output(output: &TxOutput, coin: CoinType) -> Result Result { let NftIssuance::V0(data) = data; + // Note: + // 1. Consensus rules require that name, description and ticker are ascii alphanumeric. + // But same as in the IssueFungibleToken case, we use `make_displayable` for consistency + // and simplicity. + // 2. The URIs are allowed to have non-ascii chars, so `make_displayable` is not redundant + // for them. + // 3. There is no point in reviewing the NFT id - consensus rules require that the id is + // calculated from transaction inputs and if the host cheats or malfunctions, the + // transaction will become invalid (note that the id is only present in the output due + // to historical reasons and e.g. IssueFungibleToken doesn't contain the token id). let address_short = format!( - "Name: {}\nCreator: {}\nTicker: {}\nAddress: {}\nIcon URI: {}\nAdditional metadata URI: {}\nMedia URI: {}", - String::from_utf8_lossy(data.name.as_ref()), - data.creator.clone().map(|creator| to_address(&Destination::PublicKey(creator), coin)).transpose()?.unwrap_or_default(), - String::from_utf8_lossy(data.ticker.as_ref()), + "Name: {}\nDescription: {}\nCreator: {}\nTicker: {}\nAddress: {}\nIcon URI: {}\nAdditional metadata URI: {}\nMedia URI: {}, Media hash: {}", + make_displayable(&data.name), + make_displayable(&data.description), + data.creator + .clone() + .map(|creator| to_address(&Destination::PublicKey(creator), coin)) + .transpose()? + .unwrap_or_default(), + make_displayable(&data.ticker), to_address(destination, coin)?, - String::from_utf8_lossy(data.icon_uri.as_ref()), - String::from_utf8_lossy(data.additional_metadata_uri.as_ref()), - String::from_utf8_lossy(data.media_uri.as_ref()) + make_displayable(&data.icon_uri), + make_displayable(&data.additional_metadata_uri), + make_displayable(&data.media_uri), + make_displayable(&data.media_hash), ); - let name = if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { - "Issue NFT" - } else { - "Issue NFT token" - }; - (name, address_short) + ("Issue NFT", address_short) } - TxOutput::DataDeposit(data) => ("Data deposit", hex::encode(data)), + TxOutput::DataDeposit(data) => ("Data deposit", const_hex::encode(data)), TxOutput::Htlc(value, data) => { let address_short = format!( - "Secret hash: {}\nSpend key: {}\nRefund key: {}\nRefund time lock: {}\n{}", - hex::encode(data.secret_hash.0), + "Secret hash: {:x}\nSpend key: {}\nRefund key: {}\nRefund time lock: {}\n{}", + const_hex::display(data.secret_hash.0), to_address(&data.spend_key, coin)?, to_address(&data.refund_key, coin)?, format_lock(&data.refund_timelock)?, @@ -463,20 +540,20 @@ fn format_output(output: &TxOutput, coin: CoinType) -> Result Result { +fn format_input(input: &InputCommand, coin: mlcp::CoinType) -> Result { let (name, value) = match input { InputCommand::AccountSpending(cmd) => match cmd { AccountSpending::DelegationBalance(delegation_id, amount) => { let address_short = format!( "Delegation ID: {}\nAmount: {}", - id_to_address(delegation_id.hash(), coin.delegation_id_address_prefix())?, - format_amount(*amount, coin) + delegation_id_to_address(delegation_id, coin)?, + format_coin_amount_with_name(*amount, coin) ); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { - ("Del Wdrwl", address_short) + ("Deleg wdrwl", address_short) } else { ("Delegation withdrawal", address_short) } @@ -486,25 +563,19 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result { let address_short = format!( "Token ID: {}\nAmount: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, - format_amount(*amount, coin) + token_id_to_address(token_id, coin)?, + format_atoms(*amount) ); ("Mint tokens", address_short) } AccountCommand::UnmintTokens(token_id) => { - let address_short = format!( - "Token ID: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, - ); + let address_short = format!("Token ID: {}", token_id_to_address(token_id, coin)?,); ("Unmint tokens", address_short) } AccountCommand::LockTokenSupply(token_id) => { - let address_short = format!( - "Token ID: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())? - ); + let address_short = format!("Token ID: {}", token_id_to_address(token_id, coin)?); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { - ("Lock token", address_short) + ("Lock supply", address_short) } else { ("Lock token supply", address_short) } @@ -512,7 +583,7 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result { let address_short = format!( "Token ID: {}\nIs unfreezable: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, + token_id_to_address(token_id, coin)?, if *is_unfreezable == IsTokenUnfreezable::Yes { "Yes" } else { @@ -522,10 +593,7 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result { - let address_short = format!( - "Token ID: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, - ); + let address_short = format!("Token ID: {}", token_id_to_address(token_id, coin)?,); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { ("Unfrz token", address_short) } else { @@ -535,11 +603,11 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result { let address_short = format!( "Token ID: {}\nNew authority: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, + token_id_to_address(token_id, coin)?, to_address(new_authority, coin)? ); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { - ("Chg token auth", address_short) + ("Chg tkn auth", address_short) } else { ("Change token authority", address_short) } @@ -547,40 +615,36 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result { let address_short = format!( "Token ID: {}\nNew metadata URI: {}", - id_to_address(token_id.hash(), coin.token_id_address_prefix())?, - String::from_utf8_lossy(new_metadata_uri) + token_id_to_address(token_id, coin)?, + make_displayable(new_metadata_uri) ); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { - ("Chg token meta", address_short) + ("Chg tkn meta", address_short) } else { ("Change token metadata URI", address_short) } } AccountCommand::ConcludeOrder(_) | AccountCommand::FillOrder(_, _, _) => { - return Err(StatusWord::OrdersV0NotSupported) + return Err(StatusWord::OrdersV0NotSupported); } }, - InputCommand::OrderCommand(cmd) => match cmd { + InputCommand::OrderCommand(cmd, additional_info) => match cmd { OrderAccountCommand::FillOrder(order_id, fill_amount) => { + let fill_value = + output_value_with_amount(&additional_info.initially_asked, *fill_amount); let address_short = format!( "Order ID: {}\nFill amount: {}", - id_to_address(order_id.hash(), coin.order_id_address_prefix())?, - format_amount(*fill_amount, coin), + order_id_to_address(order_id, coin)?, + format_value(&fill_value, coin)?, ); ("Fill order", address_short) } OrderAccountCommand::FreezeOrder(order_id) => { - let address_short = format!( - "Order ID: {}", - id_to_address(order_id.hash(), coin.order_id_address_prefix())? - ); + let address_short = format!("Order ID: {}", order_id_to_address(order_id, coin)?); ("Freeze order", address_short) } OrderAccountCommand::ConcludeOrder(order_id) => { - let address_short = format!( - "Order ID: {}", - id_to_address(order_id.hash(), coin.order_id_address_prefix())? - ); + let address_short = format!("Order ID: {}", order_id_to_address(order_id, coin)?); if cfg!(any(target_os = "nanosplus", target_os = "nanox")) { ("Conclude ord", address_short) } else { @@ -590,5 +654,5 @@ fn format_input(input: &InputCommand, coin: CoinType) -> Result Result { - let parsed_hrp = bech32::Hrp::parse(hrp).map_err(|_| StatusWord::TxAddressFail)?; + let parsed_hrp = bech32::Hrp::parse(hrp).map_err(|_| StatusWord::AddressEncodingFail)?; let encoded = bech32::encode::(parsed_hrp, data) - .map_err(|_| StatusWord::TxAddressFail)?; + .map_err(|_| StatusWord::AddressEncodingFail)?; Ok(encoded) } -pub fn to_address(destination: &Destination, coin: CoinType) -> Result { +pub fn to_address(destination: &Destination, coin: mlcp::CoinType) -> Result { let hrp = coin.address_prefix(destination.into()); bech32m_encode(hrp, &encode(destination)) } @@ -48,13 +42,13 @@ pub fn to_address(destination: &Destination, coin: CoinType) -> Result NbglGlyph<'static> { #[cfg(target_os = "apex_p")] const MINTLAYER: NbglGlyph = - NbglGlyph::from_include(include_gif!("../../glyphs/mintlayer_48x48.png", NBGL)); + NbglGlyph::from_include(include_gif!("../../media/glyphs/mintlayer_48x48.png", NBGL)); #[cfg(any(target_os = "stax", target_os = "flex"))] const MINTLAYER: NbglGlyph = - NbglGlyph::from_include(include_gif!("../../glyphs/mintlayer_64x64.gif", NBGL)); + NbglGlyph::from_include(include_gif!("../../media/glyphs/mintlayer_64x64.gif", NBGL)); #[cfg(any(target_os = "nanosplus", target_os = "nanox"))] const MINTLAYER: NbglGlyph = - NbglGlyph::from_include(include_gif!("../../icons/mintlayer_14x14.gif", NBGL)); + NbglGlyph::from_include(include_gif!("../../media/icons/mintlayer_14x14.gif", NBGL)); MINTLAYER } @@ -85,22 +79,12 @@ pub fn compress_public_key( } pub fn to_public_key_hash(pk: &Secp256k1PublicKey) -> Result { - let mut blake2b256 = Blake2b_512::new(); - let mut public_key_hash: [u8; 64] = [0u8; 64]; - - blake2b256 - .update(&[0]) - .map_err(|_| StatusWord::TxHashFail)?; - blake2b256 - .update(&pk.0) - .map_err(|_| StatusWord::TxHashFail)?; - - blake2b256 - .finalize(&mut public_key_hash) - .map_err(|_| StatusWord::TxHashFail)?; - - let mut pkh = [0u8; 20]; - pkh.copy_from_slice(&public_key_hash[0..20]); + let mut hasher = Hasher::new(); + + encode_to(mlcp::PublicKey::Secp256k1Schnorr(*pk), &mut hasher); + + let full_hash = hasher.finalize()?; + let pkh: [u8; PUBLIC_KEY_HASH_SIZE] = cut_array(full_hash.as_fixed_bytes()); Ok(PublicKeyHash(pkh)) } diff --git a/crates/app-core/src/errors.rs b/crates/app-core/src/errors.rs index 364bb55..f4faa50 100644 --- a/crates/app-core/src/errors.rs +++ b/crates/app-core/src/errors.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/crates/app-core/src/handlers/get_public_key.rs b/crates/app-core/src/handlers/get_public_key.rs index 86b7c44..acd5409 100644 --- a/crates/app-core/src/handlers/get_public_key.rs +++ b/crates/app-core/src/handlers/get_public_key.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,28 +15,19 @@ * limitations under the License. *****************************************************************************/ -use crate::app_ui::address::ui_display_pk; -use crate::StatusWord; +use ledger_device_sdk::ecc::{Secp256k1, SeedDerive}; + use mintlayer_messages::{ - mlcp::CoinType, ChainCode, GetPublicKeyResponse, PublicKey, PublicKeyReq, + ChainCode, GetPubKeyReq, PublicKeyResponse, UncompressedSecp256k1PublicKey, }; -use ledger_device_sdk::ecc::{Secp256k1, SeedDerive}; - -// Path should be at least [bip44, coin_type, account_index] -const MIN_PATH_LEN: usize = 3; +use crate::{StatusWord, app_ui::address::ui_display_pk, utils::check_derivation_path}; pub fn handle_get_public_key( - req: PublicKeyReq, + req: GetPubKeyReq, display: bool, -) -> Result { - if req.path.as_ref().len() < MIN_PATH_LEN { - return Err(StatusWord::InvalidPath); - } - let coin_type: CoinType = req.coin_type.into(); - if req.path.as_ref()[1] != coin_type.bip44_coin_type() { - return Err(StatusWord::InvalidPath); - } +) -> Result { + check_derivation_path(req.path.as_ref(), req.coin_type.into())?; let (k, cc) = Secp256k1::derive_from(req.path.as_ref()); let pk = k.public_key().map_err(|_| StatusWord::KeyDeriveFail)?; @@ -46,8 +37,8 @@ pub fn handle_get_public_key( if display && !ui_display_pk(&pk, req.coin_type.into())? { return Err(StatusWord::Deny); } - let response = GetPublicKeyResponse { - public_key: PublicKey(pk.pubkey), + let response = PublicKeyResponse { + public_key: UncompressedSecp256k1PublicKey(pk.pubkey), chain_code: ChainCode(code.value), }; diff --git a/crates/app-core/src/handlers/mod.rs b/crates/app-core/src/handlers/mod.rs new file mode 100644 index 0000000..82f67fc --- /dev/null +++ b/crates/app-core/src/handlers/mod.rs @@ -0,0 +1,20 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +pub mod get_public_key; +pub mod sign_message; +pub mod sign_tx; diff --git a/crates/app-core/src/handlers/sign_message.rs b/crates/app-core/src/handlers/sign_message.rs index 5a60d55..67f3736 100644 --- a/crates/app-core/src/handlers/sign_message.rs +++ b/crates/app-core/src/handlers/sign_message.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,27 +15,29 @@ * limitations under the License. *****************************************************************************/ -use crate::{ - app_ui::sign::ui_display_message, errors::cx_err_to_status, handlers::utils::mintlayer_hash, - DataContext, StatusWord, -}; -use mintlayer_messages::{ - mlcp::CoinType, AddrType, Bip32Path, MsgSignatureResponse, SignMessageReq, SignatureResponse, -}; - use alloc::vec::Vec; + use ledger_device_sdk::ecc::{ECPrivateKey, Secp256k1, SeedDerive}; use ledger_secure_sdk_sys::*; +use mintlayer_messages::{ + AddrType, Bip32Path, MsgSignatureResponse, SignMessageStartReq, Signature, +}; + +use crate::{ + DataContext, StatusWord, app_ui::sign::ui_display_message, errors::cx_err_to_status, + hasher::Hasher, mlcp, utils::check_derivation_path, +}; + pub struct SignMessageContext { path: Bip32Path, - coin: CoinType, + coin: mlcp::CoinType, addr_type: AddrType, review_finished: bool, } impl SignMessageContext { - pub fn new(req: SignMessageReq) -> Self { + pub fn new(req: SignMessageStartReq) -> Self { Self { path: req.path, coin: req.coin.into(), @@ -49,10 +51,17 @@ impl SignMessageContext { } } -pub fn setup_sign_message(req: SignMessageReq) -> DataContext { - DataContext::SignMessageContext(SignMessageContext::new(req)) +pub fn setup_sign_message(req: SignMessageStartReq) -> Result { + check_derivation_path(req.path.as_ref(), req.coin.into())?; + + Ok(DataContext::SignMessageContext(SignMessageContext::new( + req, + ))) } +// TODO: implement stateful message signing, where the message is received and displayed for review +// in portions, to allow signing messages of arbitrary sizes. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/13. pub fn handle_sign_message( message: &[u8], ctx: &mut SignMessageContext, @@ -62,7 +71,7 @@ pub fn handle_sign_message( .public_key() .map_err(|_| StatusWord::KeyDeriveFail)?; - // Display review. If user approves sign it. + // Display review. If user approves, sign it. // Otherwise, return a "deny" status word. if ui_display_message(message, &public_key, ctx.coin, ctx.addr_type)? { ctx.review_finished = true; @@ -88,13 +97,13 @@ fn compute_signature( .copied() .collect::>(); - let message_hash = mintlayer_hash(&message)?; - let message_hash2 = mintlayer_hash(message_hash.as_bytes())?; + let message_hash = Hasher::hash(&message)?; + let message_hash2 = Hasher::hash(message_hash.as_bytes())?; let sig = schnorr_sign(private_key, message_hash2.as_bytes())?; let response = MsgSignatureResponse { - signature: SignatureResponse(sig), + signature: Signature(sig), }; Ok(response) diff --git a/crates/app-core/src/handlers/sign_tx/mod.rs b/crates/app-core/src/handlers/sign_tx/mod.rs index cbde975..20a6f16 100644 --- a/crates/app-core/src/handlers/sign_tx/mod.rs +++ b/crates/app-core/src/handlers/sign_tx/mod.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,67 +17,56 @@ use alloc::{boxed::Box, vec::Vec}; +use ledger_device_sdk::{ + ecc::{Secp256k1, SeedDerive}, + nbgl::{NbglSpinner, NbglStreamingReview}, +}; + +use mintlayer_messages::{ + H256, InputAddressPath, OrderAccountCommand, Response, SignTxNextReq, SignTxStartReq, + Signature, TransactionVersion, TxInputCommitmentData, TxInputData, TxInputSignatureResponse, + TxInputWithAdditionalInfo, TxOutputData, encode_as_compact_to, encode_to, +}; + use crate::{ + DataContext, StatusWord, app_ui::sign::{ ui_approve_streaming_review, ui_new_streaming_review, ui_start_streaming_review, ui_streaming_review_show_input, ui_streaming_review_show_output, }, - handlers::{sign_message::schnorr_sign, utils::mintlayer_hash}, - DataContext, StatusWord, -}; -use mintlayer_messages::{ - encode_as_compact, encode_to, - mlcp::{CoinType as PCoinType, SighashInputCommitment, H256}, - CoinType, Encode, InputAddressPath, Response, SignTxReq, SignatureResponse, TxInputReq, - TxInputSignatureResponse, TxMetadataReq, TxMetadataV1Req, TxMetadataVersionReq, TxOutputReq, -}; - -use ledger_device_sdk::{ - ecc::{Secp256k1, SeedDerive}, - hash::{blake2::Blake2b_512, HashInit}, - nbgl::{NbglSpinner, NbglStreamingReview}, + handlers::sign_message::schnorr_sign, + hasher::Hasher, + mlcp, + utils::{CompressedDerivationPathForTxSigning, check_derivation_path_for_tx_signing}, }; mod summary_collector; -use summary_collector::TxSummaryCollector; -pub use summary_collector::{CoinOrTokenId, InputCommand, TxType}; -const BIP44: u32 = 44 + (1 << 31); +pub use summary_collector::{CoinOrTokenId, InputCommand, TxSummaryCollector, TxType}; -// BIP44/COIN/ACCOUNT/PURPOSE/INDEX -const DERIVATION_PATH_LEN: usize = 5; -// DERIVATION_PATH_LEN without the BIP44 and COIN as they are the same for all -const COMPRESSED_DERIVATION_PATH_LEN: usize = 3; - -// we try to save a few bytes instead of using usize for indexes, -// u32 is enough to cover max possible number of inputs and outputs +// u32 is enough to cover max possible number of inputs and outputs (note that usize is also +// 32-bit on Ledger, but we want to be specific about size) type Index = u32; -pub struct InputCompressed { - pub path: [u32; COMPRESSED_DERIVATION_PATH_LEN], +/// A "signature target". Usually, one input will produce one SigTarget (more than one SigTarget +/// is possible in the case of multisig; it can also be zero for non-signable pseudo-inputs, such +/// as FillOrder). +pub struct SigTarget { + pub path: CompressedDerivationPathForTxSigning, pub input_idx: Index, pub multisig_idx: Option, } -impl InputCompressed { - fn new(addr: InputAddressPath, input_idx: Index, coin: PCoinType) -> Result { - let path = addr.path.as_ref(); - if path.len() != DERIVATION_PATH_LEN { - return Err(StatusWord::TxInvalidInputPath); - } - - if path[0] != BIP44 { - return Err(StatusWord::TxInvalidInputPath); - } - - if path[1] != coin.bip44_coin_type() { - return Err(StatusWord::TxInvalidInputPath); - } +impl SigTarget { + fn new( + addr: InputAddressPath, + input_idx: Index, + coin: mlcp::CoinType, + ) -> Result { + let path = check_derivation_path_for_tx_signing(addr.path.as_ref(), coin)?; Ok(Self { - path: path[2..] - .try_into() - .map_err(|_| StatusWord::TxInvalidInputPath)?, + path, input_idx, multisig_idx: addr.multisig_idx, }) @@ -85,55 +74,93 @@ impl InputCompressed { } pub struct TxMetadata { - coin: PCoinType, + coin: mlcp::CoinType, num_inputs: Index, num_outputs: Index, } -pub struct TxParsingInputsContext { +pub struct TxInputsProcessingContext { metadata: TxMetadata, - tx_hasher: Blake2b_512, - input_commitments_hasher: Blake2b_512, + tx_hasher: Hasher, + + // Note: input commitments have to be sent together with the inputs, because they contain + // the actual amounts that the inputs consume. But they can't be put into the transaction hasher + // until all inputs have been processed, so they'll have to be sent again via a separate pass. + // We hash the commitments to ensure that the same ones are sent during both passes. + input_commitments_hasher: Hasher, summary: TxSummaryCollector, - inputs: Vec, + sig_targets: Vec, spinner: NbglSpinner, num_inputs_parsed: Index, } -pub struct TxParsingInputCommitmentsContext { +impl TxInputsProcessingContext { + fn advance_next_input_step(mut self: Box) -> Result { + self.num_inputs_parsed += 1; + let finished_with_inputs = self.num_inputs_parsed >= self.metadata.num_inputs; + + if finished_with_inputs { + if self.sig_targets.is_empty() { + return Err(StatusWord::NothingToSign); + } + + // Update hash for input commitments and proceed with outputs + self.tx_hasher + .update(&self.metadata.num_inputs.to_le_bytes()); + + let input_commitments_hash = self.input_commitments_hasher.finalize()?; + + Ok(TxProcessingContext::ProcessingInputCommitments(Box::new( + TxInputCommitmentsProcessingContext { + metadata: self.metadata, + tx_hasher: self.tx_hasher, + input_commitments_hasher: Hasher::new(), + expected_input_commitments_hash: input_commitments_hash, + summary: self.summary, + sig_targets: self.sig_targets, + spinner: self.spinner, + num_inputs_parsed: 0, + }, + ))) + } else { + Ok(TxProcessingContext::ProcessingInputs(self)) + } + } +} + +pub struct TxInputCommitmentsProcessingContext { metadata: TxMetadata, - tx_hasher: Blake2b_512, - input_commitments_hasher: Blake2b_512, - input_commitments_hash: [u8; 64], + tx_hasher: Hasher, + input_commitments_hasher: Hasher, + expected_input_commitments_hash: H256, summary: TxSummaryCollector, - inputs: Vec, + sig_targets: Vec, spinner: NbglSpinner, num_inputs_parsed: Index, } -impl TxParsingInputCommitmentsContext { +impl TxInputCommitmentsProcessingContext { fn advance_next_input_additional_info_step( mut self: Box, review: &NbglStreamingReview, - ) -> Result { - let finished_with_inputs = self.num_inputs_parsed >= (self.metadata.num_inputs - 1); + ) -> Result { + self.num_inputs_parsed += 1; + + let finished_with_inputs = self.num_inputs_parsed >= self.metadata.num_inputs; if finished_with_inputs { // Make sure the hashes match before continuing with the outputs - let mut input_commitments_hash: [u8; 64] = [0u8; 64]; - self.input_commitments_hasher - .finalize(&mut input_commitments_hash) - .map_err(|_| StatusWord::TxHashFail)?; + let input_commitments_hash = self.input_commitments_hasher.finalize()?; - if input_commitments_hash != self.input_commitments_hash { + if input_commitments_hash != self.expected_input_commitments_hash { return Err(StatusWord::DifferentInputCommitmentHash); } @@ -141,88 +168,56 @@ impl TxParsingInputCommitmentsContext { return Err(StatusWord::Deny); } - if let Some(command) = self.summary.input_command() { - if !ui_streaming_review_show_input(review, command, self.metadata.coin)? { - return Err(StatusWord::Deny); - } + if let Some(command) = self.summary.input_command() + && !ui_streaming_review_show_input(review, command, self.metadata.coin)? + { + return Err(StatusWord::Deny); } - self.tx_hasher - .update(&encode_as_compact(self.metadata.num_outputs)) - .map_err(|_| StatusWord::TxHashFail)?; - let new_context = TxParsingContext::ParsingOutputs(Box::new(TxParsingOutputsContext { - metadata: self.metadata, - - tx_hasher: self.tx_hasher, - - summary: self.summary, - inputs: self.inputs, - - spinner: self.spinner, - - num_outputs_parsed: 0, - })); - Ok(new_context) - } else { - self.num_inputs_parsed += 1; - Ok(TxParsingContext::ParsingInputCommitments(self)) - } - } -} - -impl TxParsingInputsContext { - fn advance_next_input_step(mut self: Box) -> Result { - self.num_inputs_parsed += 1; - let finished_with_inputs = self.num_inputs_parsed >= self.metadata.num_inputs; - - if finished_with_inputs { - if self.inputs.is_empty() { - return Err(StatusWord::NothingToSign); + encode_as_compact_to(self.metadata.num_outputs, &mut self.tx_hasher); + + if self.metadata.num_outputs > 0 { + let new_context = + TxProcessingContext::ProcessingOutputs(Box::new(TxOutputsProcessingContext { + metadata: self.metadata, + tx_hasher: self.tx_hasher, + summary: self.summary, + sig_targets: self.sig_targets, + spinner: self.spinner, + num_outputs_parsed: 0, + })); + Ok(new_context) + } else { + switch_to_signing( + review, + self.tx_hasher, + self.summary, + self.metadata, + self.sig_targets, + self.spinner, + ) } - - // Update hash for input commitments and proceed with outputs - self.tx_hasher - .update(&self.metadata.num_inputs.to_le_bytes()) - .map_err(|_| StatusWord::TxHashFail)?; - - let mut input_commitments_hash: [u8; 64] = [0u8; 64]; - self.input_commitments_hasher - .finalize(&mut input_commitments_hash) - .map_err(|_| StatusWord::TxHashFail)?; - - Ok(TxParsingContext::ParsingInputCommitments(Box::new( - TxParsingInputCommitmentsContext { - metadata: self.metadata, - tx_hasher: self.tx_hasher, - input_commitments_hasher: Blake2b_512::new(), - input_commitments_hash, - summary: self.summary, - inputs: self.inputs, - spinner: self.spinner, - num_inputs_parsed: 0, - }, - ))) } else { - Ok(TxParsingContext::ParsingInputs(self)) + Ok(TxProcessingContext::ProcessingInputCommitments(self)) } } } -pub struct TxParsingOutputsContext { +pub struct TxOutputsProcessingContext { metadata: TxMetadata, - tx_hasher: Blake2b_512, + tx_hasher: Hasher, summary: TxSummaryCollector, - inputs: Vec, + sig_targets: Vec, spinner: NbglSpinner, num_outputs_parsed: Index, } -impl TxParsingOutputsContext { - pub fn coin(&self) -> PCoinType { +impl TxOutputsProcessingContext { + pub fn coin(&self) -> mlcp::CoinType { self.metadata.coin } @@ -233,65 +228,77 @@ impl TxParsingOutputsContext { fn advance_next_output_state( mut self: Box, review: &NbglStreamingReview, - ) -> Result { + ) -> Result { if self.num_outputs_parsed < (self.metadata.num_outputs - 1) { self.num_outputs_parsed += 1; - Ok(TxParsingContext::ParsingOutputs(self)) + Ok(TxProcessingContext::ProcessingOutputs(self)) } else { - // Finalize the tx hash for signing - let mut message_hash: [u8; 64] = [0u8; 64]; - self.tx_hasher - .finalize(&mut message_hash) - .map_err(|_| StatusWord::TxHashFail)?; - - let tx_hash = mintlayer_hash(&message_hash[0..32])?; - - if ui_approve_streaming_review(review, &self)? { - Ok(TxParsingContext::Signing(Box::new(TxSigningContext { - metadata: self.metadata, - inputs: self.inputs, - spinner: self.spinner, - num_inputs_signed: 0, - tx_hash, - }))) - } else { - Err(StatusWord::Deny) - } + switch_to_signing( + review, + self.tx_hasher, + self.summary, + self.metadata, + self.sig_targets, + self.spinner, + ) } } } +fn switch_to_signing( + review: &NbglStreamingReview, + tx_hasher: Hasher, + summary: TxSummaryCollector, + metadata: TxMetadata, + sig_targets: Vec, + spinner: NbglSpinner, +) -> Result { + if ui_approve_streaming_review(review, &summary, metadata.coin)? { + // Finalize the tx hash for signing + let first_hash = tx_hasher.finalize()?; + let tx_hash = Hasher::hash(first_hash.as_bytes())?; + + Ok(TxProcessingContext::Signing(Box::new(TxSigningContext { + metadata, + sig_targets, + spinner, + num_sigs_produced: 0, + tx_hash, + }))) + } else { + Err(StatusWord::Deny) + } +} + pub struct TxSigningContext { metadata: TxMetadata, tx_hash: H256, - inputs: Vec, + sig_targets: Vec, spinner: NbglSpinner, - num_inputs_signed: Index, + num_sigs_produced: Index, } impl TxSigningContext { fn compute_signature_and_append( mut self: Box, - ) -> Result<(TxInputSignatureResponse, TxParsingContext), StatusWord> { - let address = self - .inputs - .get(self.num_inputs_signed as usize) + ) -> Result<(TxInputSignatureResponse, TxProcessingContext), StatusWord> { + let sig_target = self + .sig_targets + .get(self.num_sigs_produced as usize) .ok_or(StatusWord::WrongContext)?; - let [p1, p2, p3] = address.path; - let addr = [BIP44, self.metadata.coin.bip44_coin_type(), p1, p2, p3]; - - let private_key = Secp256k1::derive_from_path(&addr); + let path = sig_target.path.to_full_path(self.metadata.coin); + let private_key = Secp256k1::derive_from_path(&path); let sig = schnorr_sign(&private_key, self.tx_hash.as_bytes())?; - let signature = SignatureResponse(sig); - let input_idx = address.input_idx; - let multisig_idx = address.multisig_idx; + let signature = Signature(sig); + let input_idx = sig_target.input_idx; + let multisig_idx = sig_target.multisig_idx; - let has_next = ((self.num_inputs_signed + 1) as usize) < self.inputs.len(); + let has_next = ((self.num_sigs_produced + 1) as usize) < self.sig_targets.len(); let response = TxInputSignatureResponse { signature, @@ -301,86 +308,99 @@ impl TxSigningContext { }; let new_ctx = if has_next { - self.num_inputs_signed += 1; - TxParsingContext::Signing(self) + self.num_sigs_produced += 1; + TxProcessingContext::Signing(self) } else { - TxParsingContext::Finished + TxProcessingContext::Finished }; Ok((response, new_ctx)) } } -pub enum TxParsingContext { - ParsingInputs(Box), - ParsingInputCommitments(Box), - ParsingOutputs(Box), +pub enum TxProcessingContext { + ProcessingInputs(Box), + ProcessingInputCommitments(Box), + ProcessingOutputs(Box), Signing(Box), Finished, } -impl TxParsingContext { - pub fn from_v1( - coin: CoinType, - TxMetadataV1Req { +impl TxProcessingContext { + pub fn new( + SignTxStartReq { + coin, + version, num_inputs, num_outputs, - }: TxMetadataV1Req, + }: SignTxStartReq, ) -> Result { - const VERSION_1: u8 = 1; - let mut tx_hasher = Blake2b_512::new(); - // mode - tx_hasher - .update(b"\x01") - .map_err(|_| StatusWord::TxHashFail)?; - // version - tx_hasher - .update(&[VERSION_1]) - .map_err(|_| StatusWord::TxHashFail)?; - // flags - tx_hasher - .update(&[0; 16]) - .map_err(|_| StatusWord::TxHashFail)?; - - tx_hasher - .update(&num_inputs.to_le_bytes()) - .map_err(|_| StatusWord::TxHashFail)?; - - Ok(Self::ParsingInputs(Box::new(TxParsingInputsContext { - metadata: TxMetadata { - coin: coin.into(), - num_inputs, - num_outputs, - }, - tx_hasher, - spinner: NbglSpinner::new(), - summary: TxSummaryCollector::new(), - num_inputs_parsed: 0, - input_commitments_hasher: Blake2b_512::new(), - inputs: Vec::new(), - }))) + if num_inputs == 0 { + return Err(StatusWord::TxWithZeroInputs); + } + + match version { + TransactionVersion::V1 => { + const VERSION_1: u8 = 1; + const SIG_HASH_TYPE_ALL: u8 = 1; + + let mut tx_hasher = Hasher::new(); + // mode + tx_hasher.update(&[SIG_HASH_TYPE_ALL]); + // version + tx_hasher.update(&[VERSION_1]); + // flags + tx_hasher.update(&[0; 16]); + + tx_hasher.update(&num_inputs.to_le_bytes()); + + Ok(Self::ProcessingInputs(Box::new( + TxInputsProcessingContext { + metadata: TxMetadata { + coin: coin.into(), + num_inputs, + num_outputs, + }, + tx_hasher, + spinner: NbglSpinner::new(), + summary: TxSummaryCollector::new(), + num_inputs_parsed: 0, + input_commitments_hasher: Hasher::new(), + sig_targets: Vec::new(), + }, + ))) + } + } } - /// Shows a spinner while processing the inputs and input commitments if there are more than a few + /// Shows a spinner while processing the inputs and input commitments if there are more than a few, /// as well as while signing and returning the signatures. pub fn show_spinner(&mut self) { let (metadata, spinner) = match self { - Self::ParsingInputs(ctx) => (&ctx.metadata, &mut ctx.spinner), - Self::ParsingInputCommitments(ctx) => (&ctx.metadata, &mut ctx.spinner), + Self::ProcessingInputs(ctx) => (&ctx.metadata, &mut ctx.spinner), + Self::ProcessingInputCommitments(ctx) => (&ctx.metadata, &mut ctx.spinner), Self::Signing(ctx) => { ctx.spinner.show("Signing..."); return; } - // While parsing outputs we are showing the review and not the spinner - Self::ParsingOutputs(_) | Self::Finished => return, + // While parsing outputs we are showing the review and not the spinner. + + // TODO: inputs may need to be reviewed one by one, just like outputs. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/14. + // Also see the TODO near `TxSummaryCollector::input_command`. + + // TODO: change outputs should be detected and not presented for review; once this is + // implemented, the spinner logic may need to be revised. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/17. + Self::ProcessingOutputs(_) | Self::Finished => return, }; - // We show a spinner while processing the inputs and input commitments if there are more than 5 + // We show a spinner while processing the inputs and input commitments if there are more than 5; // 5 was chosen somewhat arbitrarily let transaction_has_many_inputs = metadata.num_inputs > 5; if transaction_has_many_inputs { - spinner.show("Parsing transaction..."); + spinner.show("Processing transaction..."); } } @@ -389,54 +409,72 @@ impl TxParsingContext { } } -pub fn setup_sign_tx(req: TxMetadataReq) -> Result { - let mut tx_ctx = match req.version { - TxMetadataVersionReq::V1(v1_req) => TxParsingContext::from_v1(req.coin, v1_req)?, - }; +pub fn setup_sign_tx(req: SignTxStartReq) -> Result { + let mut tx_ctx = TxProcessingContext::new(req)?; tx_ctx.show_spinner(); Ok(DataContext::TxContext(tx_ctx, ui_new_streaming_review())) } -fn handle_input_req( - req: Box, - mut ctx: Box, -) -> Result { +fn handle_input( + input_data: Box, + mut ctx: Box, +) -> Result { + // FillOrder inputs are pseudo-inputs that should not be signed; if the host requests + // a signature in such a case, it is doing something wrong, so we reject it. + // Note that we only check for V1 orders here, since V0 are not supported by the app + // (see StatusWord::OrdersV0NotSupported). + if is_v1_fill_order_input(&input_data.input) && !input_data.addresses.is_empty() { + return Err(StatusWord::FillOrderSigRequested); + } + let num_inputs_parsed = ctx.num_inputs_parsed; - let compressed_inputs = req + let sig_targets = input_data .addresses .into_iter() - .map(|a| InputCompressed::new(a, num_inputs_parsed, ctx.metadata.coin)) + .map(|a| SigTarget::new(a, num_inputs_parsed, ctx.metadata.coin)) .collect::, StatusWord>>()?; - ctx.inputs.extend(compressed_inputs); + ctx.sig_targets.extend(sig_targets); - ctx.summary.process_input(&req.inp)?; + ctx.summary.process_input(&input_data.input)?; - let (input, commitment) = req.inp.into_input_and_commitment(); - update_hash(&commitment, &mut ctx.input_commitments_hasher)?; - update_hash(&input, &mut ctx.tx_hasher)?; + let (input, commitment) = input_data.input.into_input_and_commitment(); + encode_to(&commitment, &mut ctx.input_commitments_hasher); + encode_to(&input, &mut ctx.tx_hasher); ctx.advance_next_input_step() } -fn handle_input_commitment_req( - req: &SighashInputCommitment, - mut ctx: Box, +fn is_v1_fill_order_input(input: &TxInputWithAdditionalInfo) -> bool { + match input { + TxInputWithAdditionalInfo::OrderAccountCommand(cmd, _) => match cmd { + OrderAccountCommand::FillOrder(_, _) => true, + OrderAccountCommand::FreezeOrder(_) | OrderAccountCommand::ConcludeOrder(_) => false, + }, + TxInputWithAdditionalInfo::Utxo(_, _) + | TxInputWithAdditionalInfo::Account(_) + | TxInputWithAdditionalInfo::AccountCommand(_, _) => false, + } +} + +fn handle_input_commitment( + comm_data: &TxInputCommitmentData, + mut ctx: Box, review: &NbglStreamingReview, -) -> Result { - update_hash(req, &mut ctx.input_commitments_hasher)?; - update_hash(req, &mut ctx.tx_hasher)?; +) -> Result { + encode_to(&comm_data.commitment, &mut ctx.input_commitments_hasher); + encode_to(&comm_data.commitment, &mut ctx.tx_hasher); ctx.advance_next_input_additional_info_step(review) } -fn handle_output_req( - req: &TxOutputReq, - mut ctx: Box, +fn handle_output( + output_data: &TxOutputData, + mut ctx: Box, review: &NbglStreamingReview, -) -> Result { - if ui_streaming_review_show_output(review, &req.out, ctx.metadata.coin)? { - ctx.summary.process_output(&req.out)?; - update_hash(&req.out, &mut ctx.tx_hasher)?; +) -> Result { + if ui_streaming_review_show_output(review, &output_data.output, ctx.metadata.coin)? { + ctx.summary.process_output(&output_data.output)?; + encode_to(&output_data.output, &mut ctx.tx_hasher); ctx.advance_next_output_state(review) } else { Err(StatusWord::Deny) @@ -444,50 +482,35 @@ fn handle_output_req( } pub fn handle_sign_tx( - req: SignTxReq, - ctx: TxParsingContext, + req: SignTxNextReq, + ctx: TxProcessingContext, review: &mut NbglStreamingReview, -) -> Result<(Response, TxParsingContext), StatusWord> { - let new_ctx = match (req, ctx) { - (SignTxReq::Input(req), TxParsingContext::ParsingInputs(ctx)) => { - handle_input_req(req, ctx)? +) -> Result<(Response, TxProcessingContext), StatusWord> { + match (req, ctx) { + (SignTxNextReq::ProcessInput(req), TxProcessingContext::ProcessingInputs(ctx)) => { + let new_ctx = handle_input(req, ctx)?; + Ok((Response::TxNext, new_ctx)) } - (SignTxReq::InputCommitment(req), TxParsingContext::ParsingInputCommitments(ctx)) => { - handle_input_commitment_req(req.as_ref(), ctx, review)? + ( + SignTxNextReq::ProcessInputCommitment(req), + TxProcessingContext::ProcessingInputCommitments(ctx), + ) => { + let new_ctx = handle_input_commitment(req.as_ref(), ctx, review)?; + Ok((Response::TxNext, new_ctx)) } - (SignTxReq::Output(req), TxParsingContext::ParsingOutputs(ctx)) => { - handle_output_req(req.as_ref(), ctx, review)? + (SignTxNextReq::ProcessOutput(req), TxProcessingContext::ProcessingOutputs(ctx)) => { + let new_ctx = handle_output(req.as_ref(), ctx, review)?; + Ok((Response::TxNext, new_ctx)) } - (SignTxReq::NextSignature, TxParsingContext::Signing(ctx)) => { - TxParsingContext::Signing(ctx) - } - (SignTxReq::NextSignature, TxParsingContext::Finished) => { - return Err(StatusWord::TxAlreadyFinished) - } - _ => return Err(StatusWord::WrongContext), - }; - - let new_ctx = match new_ctx { - ctx @ (TxParsingContext::ParsingInputs(_) - | TxParsingContext::Finished - | TxParsingContext::ParsingInputCommitments(_) - | TxParsingContext::ParsingOutputs(_)) => ctx, - TxParsingContext::Signing(ctx) => { + (SignTxNextReq::ReturnNextSignature, TxProcessingContext::Signing(ctx)) => { let (response, mut new_ctx) = ctx.compute_signature_and_append()?; new_ctx.show_spinner(); - return Ok((Response::TxSignature(response), new_ctx)); + Ok((Response::TxInputSignature(response), new_ctx)) } - }; - - Ok((Response::TxNext, new_ctx)) -} - -fn update_hash(data: &T, hasher: &mut Blake2b_512) -> Result<(), StatusWord> { - let mut buf = Vec::::new(); - encode_to(data, &mut buf); - hasher - .update(buf.as_slice()) - .map_err(|_| StatusWord::TxHashFail)?; - Ok(()) + (SignTxNextReq::ReturnNextSignature, TxProcessingContext::Finished) => { + Err(StatusWord::TxAlreadyFinished) + } + _ => Err(StatusWord::WrongContext), + } } diff --git a/crates/app-core/src/handlers/sign_tx/summary_collector.rs b/crates/app-core/src/handlers/sign_tx/summary_collector.rs index 66ee6f4..2425ea8 100644 --- a/crates/app-core/src/handlers/sign_tx/summary_collector.rs +++ b/crates/app-core/src/handlers/sign_tx/summary_collector.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,17 @@ use alloc::collections::BTreeMap; -use crate::StatusWord; use mintlayer_messages::{ - mlcp::{ - AccountCommand, AccountSpending, Amount, OrderAccountCommand, OutputValue, TxOutput, H256, - }, - AdditionalOrderInfo, AdditionalUtxoInfo, TxInputWithAdditionalInfo, + AccountCommand, AccountSpending, AdditionalOrderInfo, AdditionalUtxoInfo, Amount, + OrderAccountCommand, OutputValue, TokenId, TxInputWithAdditionalInfo, TxOutput, }; +use crate::StatusWord; + #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum CoinOrTokenId { Coin, - TokenId(H256), + TokenId(TokenId), } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -37,7 +36,7 @@ pub enum TxType { Burn, Htlc, CreateDelegation, - DelegationStake, + DelegateStaking, DelegationWithdrawal, CreateStakePool, DecommissionStakePool, @@ -61,7 +60,7 @@ pub enum TxType { pub enum InputCommand { AccountSpending(AccountSpending), AccountCommand(AccountCommand), - OrderCommand(OrderAccountCommand), + OrderCommand(OrderAccountCommand, AdditionalOrderInfo), } pub struct TxSummaryCollector { @@ -81,6 +80,15 @@ impl TxSummaryCollector { } } + // TODO: + // 1) currently consensus only forbids multiple account commands (AccountCommand or OrderAccountCommand) per tx, + // but the number of account spendings is unlimited and they can co-exist with an account command; + // 2) probably the app shouldn't try being smart and assume any number of account commands is possible, asking + // the user to approve them as they arrive, same as it's done for outputs; + // 3) if the app does try to be smart, then it should fail when multiple commands are encountered, instead of + // silently overwriting `input_command`. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/14. + // Also see the TODO near `TxProcessingContext::show_spinner`. pub fn input_command(&self) -> Option<&InputCommand> { self.input_command.as_ref() } @@ -100,6 +108,9 @@ impl TxSummaryCollector { pub fn fees_iter( &self, ) -> impl Iterator> + '_ { + // TODO: if an asset is only present in total_outputs, this will not fail with TxFeeUnderflow, + // but it should. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/15. self.total_inputs() .iter() .map(move |(coin_or_token, amount)| { @@ -144,7 +155,7 @@ impl TxSummaryCollector { } TxOutput::ProduceBlockFromStake(_, _) => {} TxOutput::DelegateStaking(amount, _) => { - self.tx_type = merge_tx_type(self.tx_type, TxType::DelegationStake); + self.tx_type = merge_tx_type(self.tx_type, TxType::DelegateStaking); self.increase_output_totals(CoinOrTokenId::Coin, *amount)?; } TxOutput::CreateDelegationId(_, _) => { @@ -201,7 +212,7 @@ impl TxSummaryCollector { } TxOutput::IssueNft(nft_id, _, _) => { self.increase_input_totals( - CoinOrTokenId::TokenId(*nft_id.hash()), + CoinOrTokenId::TokenId(*nft_id), Amount::from_atoms(1), )?; } @@ -222,13 +233,10 @@ impl TxSummaryCollector { match cmd { AccountCommand::MintTokens(token_id, amount) => { self.tx_type = merge_tx_type(self.tx_type, TxType::MintTokens); - self.increase_input_totals( - CoinOrTokenId::TokenId(*token_id.hash()), - *amount, - )?; + self.increase_input_totals(CoinOrTokenId::TokenId(*token_id), *amount)?; } AccountCommand::ConcludeOrder(_) | AccountCommand::FillOrder(_, _, _) => { - return Err(StatusWord::OrdersV0NotSupported) + return Err(StatusWord::OrdersV0NotSupported); } AccountCommand::UnmintTokens(_) => { self.tx_type = merge_tx_type(self.tx_type, TxType::UnmintTokens); @@ -250,22 +258,17 @@ impl TxSummaryCollector { } } } - TxInputWithAdditionalInfo::OrderAccountCommand( - cmd, - AdditionalOrderInfo { - initially_asked, - initially_given, - ask_balance, - give_balance, - }, - ) => { - self.input_command = Some(InputCommand::OrderCommand(cmd.clone())); + TxInputWithAdditionalInfo::OrderAccountCommand(cmd, additional_info) => { + self.input_command = Some(InputCommand::OrderCommand( + cmd.clone(), + additional_info.clone(), + )); match cmd { OrderAccountCommand::FillOrder(_, fill_amount) => { let (fill_coin_or_token_id, asked_amount) = - into_coin_or_token_id_and_amount(initially_asked)?; + into_coin_or_token_id_and_amount(&additional_info.initially_asked)?; let (given_coin_or_token_id, given_amount) = - into_coin_or_token_id_and_amount(initially_given)?; + into_coin_or_token_id_and_amount(&additional_info.initially_given)?; self.increase_output_totals(fill_coin_or_token_id, *fill_amount)?; @@ -282,12 +285,12 @@ impl TxSummaryCollector { } OrderAccountCommand::ConcludeOrder(_) => { let (coin_or_token_id, _) = - into_coin_or_token_id_and_amount(initially_asked)?; - self.increase_input_totals(coin_or_token_id, *ask_balance)?; + into_coin_or_token_id_and_amount(&additional_info.initially_asked)?; + self.increase_input_totals(coin_or_token_id, additional_info.ask_balance)?; let (coin_or_token_id, _) = - into_coin_or_token_id_and_amount(initially_given)?; - self.increase_input_totals(coin_or_token_id, *give_balance)?; + into_coin_or_token_id_and_amount(&additional_info.initially_given)?; + self.increase_input_totals(coin_or_token_id, additional_info.give_balance)?; self.tx_type = merge_tx_type(self.tx_type, TxType::ConcludeOrder); } @@ -336,6 +339,10 @@ impl TxSummaryCollector { } } +// TODO: this logic makes the tx type depend on the outputs order: +// if the outputs are Burn and Transfer, the tx type will be Burn, but if it's Transfer, Burn, +// then the tx type will be ComplexTransaction. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/21. fn merge_tx_type(tx_type: Option, new_type: TxType) -> Option { match tx_type { None => Some(new_type), @@ -350,20 +357,16 @@ fn into_coin_or_token_id_and_amount( ) -> Result<(CoinOrTokenId, Amount), StatusWord> { match value { OutputValue::Coin(amount) => Ok((CoinOrTokenId::Coin, *amount)), - OutputValue::TokenV1(token_id, amount) => { - Ok((CoinOrTokenId::TokenId(*token_id.hash()), *amount)) - } + OutputValue::TokenV1(token_id, amount) => Ok((CoinOrTokenId::TokenId(*token_id), *amount)), } } #[cfg(test)] mod tests { - use crate::testing::prelude::*; - use crate::StatusWord; + use mintlayer_messages::{AdditionalOrderInfo, AdditionalUtxoInfo, TxInputWithAdditionalInfo}; + use test_utils::prelude::*; - use mintlayer_messages::{ - mlcp, AdditionalOrderInfo, AdditionalUtxoInfo, TxInputWithAdditionalInfo, - }; + use crate::{StatusWord, mlcp}; use super::*; @@ -374,6 +377,16 @@ mod tests { ) } + // TODO: these tests can be improved: + // 1) Each test should better check everything (total inputs, total outputs, fees, tx type etc), + // even if it's only dealing with one aspect of the summary collector (e.g. tx outputs). + // 2) More tests for fee calculation would be nice: + // a) non-trivial successful case; + // b) cases dealing with more than once currency (both successful and not), in particular + // the case where one currency is only present in the total outputs but not total inputs. + // 3) Maybe something else. + // See https://github.com/mintlayer/mintlayer-ledger-app/issues/15. + #[test_item] fn test_new_and_getters() { let collector = TxSummaryCollector::new(); @@ -404,7 +417,7 @@ mod tests { let token_id = mlcp::Id::new(mlcp::H256::zero()); let token_amount = mlcp::Amount::from_atoms(200); let out_token = mlcp::TxOutput::Transfer( - mlcp::OutputValue::TokenV1(token_id.clone(), token_amount), + mlcp::OutputValue::TokenV1(token_id, token_amount), mlcp::Destination::AnyoneCanSpend, ); collector.process_output(&out_token).unwrap(); @@ -412,7 +425,7 @@ mod tests { assert_eq!( collector .total_outputs() - .get(&CoinOrTokenId::TokenId(*token_id.hash())), + .get(&CoinOrTokenId::TokenId(token_id)), Some(&token_amount) ); } @@ -507,7 +520,7 @@ mod tests { let out = mlcp::TxOutput::DelegateStaking(delegate_amount, mlcp::Id::new(mlcp::H256::zero())); collector.process_output(&out).unwrap(); - assert_eq!(collector.tx_type(), Some(TxType::DelegationStake)); + assert_eq!(collector.tx_type(), Some(TxType::DelegateStaking)); assert_eq!( collector.total_outputs().get(&CoinOrTokenId::Coin), Some(&delegate_amount) @@ -699,7 +712,7 @@ mod tests { let inp = TxInputWithAdditionalInfo::Utxo( make_utxo_outpoint(), AdditionalUtxoInfo::Utxo(mlcp::TxOutput::IssueNft( - nft_id.clone(), + nft_id, nft_issuance, mlcp::Destination::AnyoneCanSpend, )), @@ -708,7 +721,7 @@ mod tests { assert_eq!( collector .total_inputs() - .get(&CoinOrTokenId::TokenId(*nft_id.hash())), + .get(&CoinOrTokenId::TokenId(nft_id)), Some(&mlcp::Amount::from_atoms(1)) ); } @@ -768,14 +781,14 @@ mod tests { let mint_amount = mlcp::Amount::from_atoms(1000); let inp = TxInputWithAdditionalInfo::AccountCommand( mlcp::AccountNonce(1), - mlcp::AccountCommand::MintTokens(token_id.clone(), mint_amount), + mlcp::AccountCommand::MintTokens(token_id, mint_amount), ); collector.process_input(&inp).unwrap(); assert_eq!(collector.tx_type(), Some(TxType::MintTokens)); assert_eq!( collector .total_inputs() - .get(&CoinOrTokenId::TokenId(*token_id.hash())), + .get(&CoinOrTokenId::TokenId(token_id)), Some(&mint_amount) ); assert!(matches!( @@ -896,7 +909,8 @@ mod tests { assert!(matches!( collector.input_command(), Some(InputCommand::OrderCommand( - mlcp::OrderAccountCommand::FillOrder(_, _) + mlcp::OrderAccountCommand::FillOrder(_, _), + AdditionalOrderInfo { .. } )) )); } @@ -910,10 +924,7 @@ mod tests { let token_id = mlcp::Id::new(mlcp::H256::zero()); let additional_info = AdditionalOrderInfo { initially_asked: mlcp::OutputValue::Coin(mlcp::Amount::from_atoms(100)), - initially_given: mlcp::OutputValue::TokenV1( - token_id.clone(), - mlcp::Amount::from_atoms(200), - ), + initially_given: mlcp::OutputValue::TokenV1(token_id, mlcp::Amount::from_atoms(200)), ask_balance, give_balance, }; @@ -931,7 +942,7 @@ mod tests { assert_eq!( collector .total_inputs() - .get(&CoinOrTokenId::TokenId(*token_id.hash())), + .get(&CoinOrTokenId::TokenId(token_id)), Some(&give_balance) ); } diff --git a/crates/app-core/src/handlers/utils.rs b/crates/app-core/src/handlers/utils.rs deleted file mode 100644 index d43404b..0000000 --- a/crates/app-core/src/handlers/utils.rs +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** - * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *****************************************************************************/ - -use crate::StatusWord; - -use mintlayer_messages::mlcp::H256; - -use ledger_device_sdk::hash::{blake2::Blake2b_512, HashInit}; - -pub fn mintlayer_hash(data: &[u8]) -> Result { - let mut hasher = Blake2b_512::new(); - let mut message_hash: [u8; 64] = [0u8; 64]; - hasher - .hash(data, &mut message_hash) - .map_err(|_| StatusWord::TxHashFail)?; - - Ok(H256::from_slice(&message_hash[..32])) -} diff --git a/crates/app-core/src/hasher.rs b/crates/app-core/src/hasher.rs new file mode 100644 index 0000000..85932b4 --- /dev/null +++ b/crates/app-core/src/hasher.rs @@ -0,0 +1,75 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +use crate::StatusWord; + +use mintlayer_messages::{H256, parity_scale_codec}; + +use ledger_device_sdk::hash::{HashInit, blake2::Blake2b_512}; + +/// The hasher that produces Mintlayer-specific hashes. +/// +/// Note: we want to implement `parity_scale_codec::Output` for `Hasher`, which means that +/// its `update` method has to be infallible. But we don't want to `expect` on errors, so +/// on failure we just set `update_failed` to true, which will then cause `finalize` to fail. +pub struct Hasher { + hasher: Blake2b_512, + update_failed: bool, +} + +impl Hasher { + pub fn new() -> Self { + Self { + hasher: Blake2b_512::new(), + update_failed: false, + } + } + + pub fn update(&mut self, input: &[u8]) { + if self.update_failed { + return; + } + + if self.hasher.update(input).is_err() { + self.update_failed = true; + } + } + + pub fn finalize(mut self) -> Result { + if self.update_failed { + return Err(StatusWord::HashFail); + } + + let mut hash: [u8; 64] = [0u8; 64]; + self.hasher + .finalize(&mut hash) + .map_err(|_| StatusWord::HashFail)?; + Ok(H256::from_slice(&hash[..32])) + } + + pub fn hash(input: &[u8]) -> Result { + let mut hasher = Self::new(); + hasher.update(input); + hasher.finalize() + } +} + +impl parity_scale_codec::Output for Hasher { + fn write(&mut self, bytes: &[u8]) { + self.update(bytes) + } +} diff --git a/crates/app-core/src/lib.rs b/crates/app-core/src/lib.rs index 19ffc16..8b8f2cd 100644 --- a/crates/app-core/src/lib.rs +++ b/crates/app-core/src/lib.rs @@ -1,8 +1,7 @@ /***************************************************************************** - * * Mintlayer Ledger App. * (c) 2023 Ledger SAS. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,37 +17,22 @@ *****************************************************************************/ #![no_std] -// The following is needed to be able to generate a test executable that can be run on speculos. -// 1. Disable the generation of `fn main`. +// See the comment in `crates/test-utils/src/lib.rs` for the meaning of these attributes. #![cfg_attr(test, no_main)] -// 2. "custom_test_frameworks" must be enabled to be able to specify the custom runner and use -// the `#[test_case]` attribute (used internally by `testmacro::test_item`). #![feature(custom_test_frameworks)] -// 3. Specify the custom test runner. All test cases collected by `#[test_case]` will be passed -// to this function. In particular, `sdk_test_runner` will loop over the array of test cases and: -// a) fix references stored inside the test case via pic_rs/pic; -// b) invoke the closure associated with the test case. #![test_runner(ledger_device_sdk::testing::sdk_test_runner)] -// 4. This will put `fn test_main` at the test crate's root, which will call the runner that we've -// specified above; we'll call it from our `sample_main`. #![reexport_test_harness_main = "test_main"] -mod app_ui { - pub mod address; - pub mod menu; - pub mod sign; - pub mod utils; -} -mod handlers { - pub mod get_public_key; - pub mod sign_message; - pub mod sign_tx; - pub mod utils; -} +#[cfg(test)] +test_utils::impl_panic_handler!(); +#[cfg(test)] +test_utils::impl_main!(); +mod app_ui; mod errors; -#[cfg(test)] -mod testing; +mod handlers; +mod hasher; +mod utils; // Required for using String, Vec, format!... extern crate alloc; @@ -56,22 +40,33 @@ use alloc::vec::Vec; use ledger_device_sdk::{ io::{ApduHeader, Comm, Reply}, - nbgl::{init_comm, NbglHomeAndSettings, NbglReviewStatus, NbglStreamingReview, StatusType}, + nbgl::{NbglHomeAndSettings, NbglReviewStatus, NbglStreamingReview, StatusType, init_comm}, }; -use app_ui::menu::ui_menu_main; -use errors::sdk_err_to_status; -use handlers::{ - get_public_key::handle_get_public_key, - sign_message::{handle_sign_message, setup_sign_message, SignMessageContext}, - sign_tx::{handle_sign_tx, setup_sign_tx, TxParsingContext}, -}; +use mintlayer_core_primitives as mlcp; + use mintlayer_messages::{ - decode_all, encode, Ins, PubKeyP1, Response, SignP1, StatusWord, APDU_CLASS, MAX_ADPU_DATA_LEN, - P2_DONE, P2_MORE, + APDU_CLASS, GetPubKeyP1, Ins, MAX_APDU_DATA_LEN, PingP1, Response, SignMsgP1, SignTxP1, + StatusWord, decode_all, encode, +}; + +use self::{ + app_ui::menu::ui_menu_main, + errors::sdk_err_to_status, + handlers::{ + get_public_key::handle_get_public_key, + sign_message::{SignMessageContext, handle_sign_message, setup_sign_message}, + sign_tx::{TxProcessingContext, handle_sign_tx, setup_sign_tx}, + }, }; -pub const MAX_BUFFER_LEN: usize = 4 * MAX_ADPU_DATA_LEN; +/// 16 max APDUs (= 4080 bytes) was chosen because: +/// * it should be enough to hold our biggest TxOutput (IssueNft with max possible URIs and other +/// fields will be slightly bigger than 3Kb); +/// * a buffer bigger than this will likely lead to OOM and crash (reallocating a 4Kb Vec will +/// temporarily consume 8Kb of RAM, which is half of the entire available Rust heap, see HEAP_SIZE +/// in .cargo/config.toml). +pub const MAX_BUFFER_LEN: usize = 16 * MAX_APDU_DATA_LEN; /// Represents a fully assembled Low-Level Instruction. /// Contains the aggregated data from one or more APDUs (if P2 indicated more data). @@ -137,8 +132,8 @@ impl ApduTransport { self.buffer.extend_from_slice(data); match header.p2 { - P2_MORE => Ok(ReceiveInstructionResult::ExpectingNextChunk), - P2_DONE => { + mintlayer_messages::P2_MORE => Ok(ReceiveInstructionResult::ExpectingNextChunk), + mintlayer_messages::P2_DONE => { // Construct the full instruction let raw = RawInstruction { ins: header.ins, @@ -163,9 +158,9 @@ impl ApduTransport { } pub enum Command { - GetPubkey { p1: PubKeyP1, data: Vec }, - SignTx { p1: SignP1, data: Vec }, - SignMessage { p1: SignP1, data: Vec }, + GetPubKey { p1: GetPubKeyP1, data: Vec }, + SignTx { p1: SignTxP1, data: Vec }, + SignMessage { p1: SignMsgP1, data: Vec }, Ping, } @@ -174,27 +169,36 @@ impl TryFrom for Command { fn try_from(raw: RawInstruction) -> Result { match raw.ins { - Ins::PUB_KEY => { - let p1: PubKeyP1 = raw.p1.try_into()?; - Ok(Command::GetPubkey { p1, data: raw.data }) + Ins::GET_PUB_KEY => { + let p1: GetPubKeyP1 = raw.p1.try_into()?; + Ok(Command::GetPubKey { p1, data: raw.data }) } Ins::SIGN_TX => { - let p1: SignP1 = raw.p1.try_into()?; + let p1: SignTxP1 = raw.p1.try_into()?; Ok(Command::SignTx { p1, data: raw.data }) } Ins::SIGN_MSG => { - let p1: SignP1 = raw.p1.try_into()?; + let p1: SignMsgP1 = raw.p1.try_into()?; Ok(Command::SignMessage { p1, data: raw.data }) } - Ins::PING => Ok(Command::Ping), + Ins::PING => { + let _p1: PingP1 = raw.p1.try_into()?; + + // Ping doesn't have any associated data. + if !raw.data.is_empty() { + Err(StatusWord::InvalidData) + } else { + Ok(Command::Ping) + } + } _ => Err(StatusWord::InsNotSupported), } } } -fn show_status_and_home_if_needed(cmd: &Command, ctx: &mut AppContext, status: &StatusWord) { +fn show_status_and_home_if_needed(cmd: &Command, ctx: &mut AppContext, status: StatusWord) { let (show_status, status_type) = match (cmd, status) { - (Command::GetPubkey { p1, .. }, StatusWord::Deny | StatusWord::Ok) if p1.display() => { + (Command::GetPubKey { p1, .. }, StatusWord::Deny | StatusWord::Ok) if p1.display() => { (true, StatusType::Address) } (Command::SignTx { .. }, StatusWord::Deny | StatusWord::Ok) if ctx.finished() => { @@ -211,7 +215,7 @@ fn show_status_and_home_if_needed(cmd: &Command, ctx: &mut AppContext, status: & }; if show_status { - let success = *status == StatusWord::Ok; + let success = status == StatusWord::Ok; NbglReviewStatus::new() .status_type(status_type) .show(success); @@ -222,7 +226,7 @@ fn show_status_and_home_if_needed(cmd: &Command, ctx: &mut AppContext, status: & } pub enum DataContext { - TxContext(TxParsingContext, NbglStreamingReview), + TxContext(TxProcessingContext, NbglStreamingReview), SignMessageContext(SignMessageContext), } @@ -250,12 +254,12 @@ impl AppContext { pub fn mintlayer_main() { let mut comm = Comm::new().set_expected_cla(APDU_CLASS); - let mut tx_ctx = AppContext::new(); + let mut app_ctx = AppContext::new(); // Initialize reference to Comm instance for NBGL API calls. init_comm(&mut comm); - tx_ctx.home = ui_menu_main(); - tx_ctx.home.show_and_return(); + app_ctx.home = ui_menu_main(); + app_ctx.home.show_and_return(); let mut transport = ApduTransport::default(); @@ -282,7 +286,7 @@ pub fn mintlayer_main() { } }; - let status = match handle_command(&command, &mut tx_ctx) { + let status = match handle_command(&command, &mut app_ctx) { Ok(response) => { comm.append(&encode(response)); comm.reply_ok(); @@ -294,23 +298,38 @@ pub fn mintlayer_main() { } }; - show_status_and_home_if_needed(&command, &mut tx_ctx, &status); + show_status_and_home_if_needed(&command, &mut app_ctx, status); } } +// TODO: +// 1) On all errors, the context should probably be reset. +// 2) Note that the simple `ctx.data_context = None` doesn't reset the UI, while `show_status_and_home_if_needed` +// doesn't reset the UI on any error. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/12. +// Also see the TODO inside the function. fn handle_command(cmd: &Command, ctx: &mut AppContext) -> Result { match cmd { - Command::GetPubkey { p1, data } => { + Command::GetPubKey { p1, data } => { + // TODO: the context should be reset here, especially if `display` is true. + // Note that `show_status_and_home_if_needed` calls `ctx.home.show_and_return()` + // on Pings, so: + // a) the context should be reset on Command::Ping below as well, + // b) since a Ping resets the context, then GetPubKey should do it even if `display` + // is false; + // c) Command::SignMessage below should also reset the context when it's done. + // In any case, it's better to put UI update (at least on success) in the same place where + // the context is changed. let req = decode_all(data).ok_or(StatusWord::DeserializeFail)?; handle_get_public_key(req, p1.display()).map(Response::PublicKey) } Command::SignTx { p1, data } => match p1 { - SignP1::Start => { + SignTxP1::Start => { let req = decode_all(data).ok_or(StatusWord::DeserializeFail)?; ctx.data_context = Some(setup_sign_tx(req)?); Ok(Response::TxSetup) } - SignP1::Next => { + SignTxP1::Next => { let (mut tx_ctx, mut review) = match ctx.data_context.take() { Some(DataContext::TxContext(c, r)) => (c, r), _ => return Err(StatusWord::WrongContext), @@ -318,6 +337,8 @@ fn handle_command(cmd: &Command, ctx: &mut AppContext) -> Result Result match p1 { - SignP1::Start => { + SignMsgP1::Start => { let req = decode_all(data).ok_or(StatusWord::DeserializeFail)?; - ctx.data_context = Some(setup_sign_message(req)); + ctx.data_context = Some(setup_sign_message(req)?); Ok(Response::MessageSetup) } - SignP1::Next => { + SignMsgP1::Next => { let msg_ctx = match ctx.data_context.as_mut() { Some(DataContext::SignMessageContext(ctx)) => ctx, _ => return Err(StatusWord::WrongContext), diff --git a/crates/app-core/src/testing.rs b/crates/app-core/src/testing.rs deleted file mode 100644 index 8b75de4..0000000 --- a/crates/app-core/src/testing.rs +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** - * - * Mintlayer Ledger App. - * (c) 2023 Ledger SAS. - * (c) 2026 RBB S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *****************************************************************************/ - -use alloc::{borrow::ToOwned as _, format}; - -pub mod prelude { - // testmacro::test_item expects `TestType` to be imported. - pub use ledger_device_sdk::testing::TestType; - - pub use testmacro::test_item; -} - -#[no_mangle] -extern "C" fn sample_main() { - crate::test_main(); - ledger_device_sdk::exit_app(0); -} - -#[panic_handler] -fn handle_panic(info: &core::panic::PanicInfo) -> ! { - ledger_device_sdk::error!( - "Panic occurred at {}: {}", - info.location().map_or_else( - || "???".to_owned(), - |loc| format!("{}:{}", loc.file(), loc.line()) - ), - info.message(), - ); - - ledger_device_sdk::exit_app(1); -} diff --git a/crates/app-core/src/utils.rs b/crates/app-core/src/utils.rs new file mode 100644 index 0000000..e9a4f3c --- /dev/null +++ b/crates/app-core/src/utils.rs @@ -0,0 +1,216 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +use alloc::{borrow::Cow, format}; +use core::fmt; + +use mintlayer_messages::{Amount, OutputValue, StatusWord}; + +use crate::mlcp; + +const DERIV_PATH_IDX_BIP44: usize = 0; +const DERIV_PATH_IDX_COIN_TYPE: usize = 1; +const DERIV_PATH_IDX_ACCOUNT_IDX: usize = 2; +const DERIV_PATH_IDX_ADDR_PURPOSE: usize = 3; +const DERIV_PATH_IDX_ADDR_IDX: usize = 4; + +// Path should be at least [bip44, coin_type, account_index] +const DERIV_PATH_MIN_LEN: usize = 3; +// For tx signing the path should also contain the purpose and the index. +const DERIV_PATH_LEN_FOR_TX_SIGNING: usize = 5; + +const DERIV_PATH_BIP44_ITEM: u32 = 44 + (1 << 31); + +pub fn check_derivation_path(path: &[u32], coin_type: mlcp::CoinType) -> Result<(), StatusWord> { + if path.len() < DERIV_PATH_MIN_LEN { + return Err(StatusWord::InvalidPath); + } + + if path[DERIV_PATH_IDX_BIP44] != DERIV_PATH_BIP44_ITEM { + return Err(StatusWord::InvalidPath); + } + + if path[DERIV_PATH_IDX_COIN_TYPE] != coin_type.bip44_coin_type() { + return Err(StatusWord::InvalidPath); + } + + Ok(()) +} + +pub fn check_derivation_path_for_tx_signing( + path: &[u32], + coin_type: mlcp::CoinType, +) -> Result { + check_derivation_path(path, coin_type)?; + + if path.len() != DERIV_PATH_LEN_FOR_TX_SIGNING { + return Err(StatusWord::InvalidPath); + } + + Ok(CompressedDerivationPathForTxSigning { + account_index: path[DERIV_PATH_IDX_ACCOUNT_IDX], + addr_purpose: path[DERIV_PATH_IDX_ADDR_PURPOSE], + addr_index: path[DERIV_PATH_IDX_ADDR_IDX], + }) +} + +pub struct CompressedDerivationPathForTxSigning { + pub account_index: u32, + pub addr_purpose: u32, + pub addr_index: u32, +} + +impl CompressedDerivationPathForTxSigning { + pub fn to_full_path(&self, coin_type: mlcp::CoinType) -> [u32; DERIV_PATH_LEN_FOR_TX_SIGNING] { + [ + DERIV_PATH_BIP44_ITEM, + coin_type.bip44_coin_type(), + self.account_index, + self.addr_purpose, + self.addr_index, + ] + } +} + +/// Cut an array of Copy types to a smaller size. +/// +/// Fail at compile time if the destination size is bigger than the original. +pub fn cut_array( + orig: &[T; ORIG_SIZE], +) -> [T; DEST_SIZE] +where + T: Default + Copy, +{ + const { assert!(DEST_SIZE <= ORIG_SIZE) }; + + let mut result = [T::default(); DEST_SIZE]; + result.copy_from_slice(&orig[..DEST_SIZE]); + result +} + +/// If `bytes` consists of only "displayable" ASCII chars, return the ASCII string directly +/// in the borrowed form. +/// Otherwise return hex-encode bytes as a newly allocated string. +pub fn make_displayable_str(bytes: &[u8]) -> Cow<'_, str> { + if let Some(s) = as_displayable_chars(bytes) { + Cow::Borrowed(s) + } else { + Cow::Owned(format!("{:#x}", const_hex::display(bytes))) + } +} + +/// This is similar to `make_displayable_str`, but instead of returning a string it returns +/// an object that will produce the string during formatting. +/// +/// This should be preferred to `make_displayable_str` if the result has to be passed to +/// `format!` anyway, because it should result in fewer reallocations. +pub fn make_displayable<'a>(bytes: &'a [u8]) -> impl fmt::Display + 'a { + if let Some(s) = as_displayable_chars(bytes) { + DisplayableMessage::Str(s) + } else { + DisplayableMessage::Hex(bytes) + } +} + +enum DisplayableMessage<'a> { + Str(&'a str), + Hex(&'a [u8]), +} + +impl<'a> fmt::Display for DisplayableMessage<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Str(s) => f.write_str(s), + Self::Hex(bytes) => { + write!(f, "{:#x}", const_hex::display(bytes)) + } + } + } +} + +fn as_displayable_chars(bytes: &[u8]) -> Option<&'_ str> { + let as_str = core::str::from_utf8(bytes).ok()?; + as_str + .bytes() + .all(|b| (0x20..=0x7E).contains(&b)) + .then_some(as_str) +} + +pub fn output_value_with_amount(value: &OutputValue, amount: Amount) -> OutputValue { + match value { + OutputValue::Coin(_) => OutputValue::Coin(amount), + OutputValue::TokenV1(token_id, _) => OutputValue::TokenV1(*token_id, amount), + } +} + +#[cfg(test)] +mod tests { + use test_utils::prelude::*; + + use super::*; + + #[test_item] + fn test_make_displayable() { + // ASCII displayable string. + { + let data = "qwe123".as_bytes(); + let expected_res = "qwe123"; + + let res = make_displayable_str(data); + assert_eq!(res, expected_res); + + let res = format!("{}", make_displayable(data)); + assert_eq!(res, expected_res); + } + + // ASCII non-displayable string. + { + let data = "qwe\t123".as_bytes(); + let expected_res = "0x71776509313233"; + + let res = make_displayable_str(data); + assert_eq!(res, expected_res); + + let res = format!("{}", make_displayable(data)); + assert_eq!(res, expected_res); + } + + // Non-ASCII string. + { + let data = "今日は".as_bytes(); + let expected_res = "0xe4bb8ae697a5e381af"; + + let res = make_displayable_str(data); + assert_eq!(res, expected_res); + + let res = format!("{}", make_displayable(data)); + assert_eq!(res, expected_res); + } + + // Not a string. + { + let data = [0xAA, 0xBB, 0xCC]; + let expected_res = "0xaabbcc"; + + let res = make_displayable_str(&data); + assert_eq!(res, expected_res); + + let res = format!("{}", make_displayable(&data)); + assert_eq!(res, expected_res); + } + } +} diff --git a/crates/messages/Cargo.toml b/crates/messages/Cargo.toml index 03edaeb..438ef1e 100644 --- a/crates/messages/Cargo.toml +++ b/crates/messages/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] derive_more = { workspace = true, default-features = false, features = ["display"]} num_enum = { workspace = true, default-features = false } +num-traits = { workspace = true, default-features = false } # Note: normally we would enable the "chain-error" feature of parity-scale-codec to make decode errors # more informative. But in the Ledger app we never examine or even print those errors, so enabling this # feature would only increase the size of the binary and make the app use more stack during decoding. @@ -13,8 +14,7 @@ parity-scale-codec = { workspace = true, default-features = false, features = [" mintlayer-core-primitives.workspace = true -[lib] -# Note: this crate doesn't have unit tests at the moment. If we ever need them, a custom runner -# has to be set up the same way it's done in `mintlayer-app-core`. For now we just disable tests -# completely to prevent Cargo from producing an uncompilable test binary. -test = false +[dev-dependencies] +ledger_device_sdk.workspace = true + +test-utils.workspace = true diff --git a/crates/messages/src/lib.rs b/crates/messages/src/lib.rs index 7bf1498..5aa632c 100644 --- a/crates/messages/src/lib.rs +++ b/crates/messages/src/lib.rs @@ -1,6 +1,6 @@ /***************************************************************************** * Mintlayer Ledger App. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,33 @@ *****************************************************************************/ #![no_std] +// See the comment in `crates/test-utils/src/lib.rs` for the meaning of these attributes. +#![cfg_attr(test, no_main)] +#![feature(custom_test_frameworks)] +#![test_runner(ledger_device_sdk::testing::sdk_test_runner)] +#![reexport_test_harness_main = "test_main"] + +#[cfg(test)] +test_utils::impl_panic_handler!(); +#[cfg(test)] +test_utils::impl_main!(); + +#[cfg(test)] +mod tests; + +// TODO: need tests that ensure encoding stability - encode a certain message or a message part and +// expect concrete bytes, decode it back, expect the same object. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/16. + +// TODO: types from mintlayer core primitives should probably not be used as part of the protocol +// (but note that this will increase the size of the binary slightly - a test attempt at using distinct +// types increased the binary from ~100Kb to ~106Kb). +// Alternatively, we may want to keep some basic mlcp types in the protocol (the primitives that +// won't ever change). Though note that we'll have to have a separate type for Destination if we +// want to be able to detect change addresses, so all types that contain Destination will have to +// be distinct as well. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/18. +// Also see the TODO in `tests/application_client/__init__.py`. // Required for using String, Vec, format!... extern crate alloc; @@ -24,14 +51,24 @@ use alloc::{boxed::Box, vec::Vec}; use core::iter::ExactSizeIterator; use derive_more::Display; +use mintlayer_core_primitives as mlcp; use num_enum::{IntoPrimitive, TryFromPrimitive}; use parity_scale_codec::{Decode, DecodeAll}; -pub use mintlayer_core_primitives as mlcp; -pub use parity_scale_codec::Encode; +pub use parity_scale_codec::{self, Encode}; + +pub use mlcp::{ + AccountCommand, AccountNonce, AccountOutPoint, AccountSpending, Amount, BlockHeight, + BlockTimestamp, BlocksCount, DelegationId, Destination, GenBlockId, H256, + HashedTimelockContract, IsTokenFreezable, IsTokenUnfreezable, NftIssuance, OrderAccountCommand, + OrderData, OrderId, OutPointSourceId, OutputTimeLock, OutputValue, PerThousand, PoolId, + PublicKey, PublicKeyHash, ScriptId, SecondsCount, Secp256k1PublicKey, SighashInputCommitment, + StakePoolData, TokenId, TokenIssuance, TokenTotalSupply, TransactionId, TxInput, TxOutput, + UtxoOutPoint, VrfPublicKey, +}; pub const APDU_CLASS: u8 = 0xE1; -pub const MAX_ADPU_DATA_LEN: usize = u8::MAX as usize; +pub const MAX_APDU_DATA_LEN: usize = u8::MAX as usize; // P2 is used to indicate APDU chunking. // `P2_DONE` marks the final chunk, while `P2_MORE` indicates that more chunks follow. @@ -42,33 +79,41 @@ fn wrong_p1p2(_: u8) -> StatusWord { StatusWord::WrongP1P2 } +pub struct Ins {} + +impl Ins { + pub const GET_PUB_KEY: u8 = 0x00; + pub const SIGN_TX: u8 = 0x01; + pub const SIGN_MSG: u8 = 0x02; + pub const PING: u8 = 0x03; +} + #[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] #[num_enum(error_type(name = StatusWord, constructor = wrong_p1p2))] #[repr(u8)] -pub enum PubKeyP1 { +pub enum GetPubKeyP1 { NoDisplayAddress = 0, DisplayAddress = 1, } -impl PubKeyP1 { +impl GetPubKeyP1 { pub fn display(&self) -> bool { *self == Self::DisplayAddress } } -pub struct Ins {} - -impl Ins { - pub const PUB_KEY: u8 = 0x00; - pub const SIGN_TX: u8 = 0x01; - pub const SIGN_MSG: u8 = 0x02; - pub const PING: u8 = 0x03; +#[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[num_enum(error_type(name = StatusWord, constructor = wrong_p1p2))] +#[repr(u8)] +pub enum SignTxP1 { + Start = 0, + Next = 1, } #[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] #[num_enum(error_type(name = StatusWord, constructor = wrong_p1p2))] #[repr(u8)] -pub enum SignP1 { +pub enum SignMsgP1 { Start = 0, Next = 1, } @@ -77,78 +122,127 @@ pub enum SignP1 { #[num_enum(error_type(name = StatusWord, constructor = wrong_p1p2))] #[repr(u8)] pub enum PingP1 { - Start = 0, + // Ping doesn't have parameters, so its P1 must always be zero. + Dummy = 0, } #[derive(Encode, Decode)] -pub struct PublicKeyReq { +pub struct GetPubKeyReq { pub coin_type: CoinType, pub path: Bip32Path, } #[derive(Encode, Decode)] -pub struct SignMessageReq { +pub struct SignMessageStartReq { pub coin: CoinType, pub addr_type: AddrType, pub path: Bip32Path, } -#[derive(Encode, Decode)] -pub enum SignTxReq { - Input(Box), - InputCommitment(Box), - Output(Box), - NextSignature, +#[derive(Debug, Clone, Copy, Eq, PartialEq, Encode, Decode)] +#[repr(u8)] +pub enum TransactionVersion { + #[codec(index = 0)] + V1, } #[derive(Encode, Decode)] -pub struct TxMetadataV1Req { +pub struct SignTxStartReq { + pub coin: CoinType, + pub version: TransactionVersion, pub num_inputs: u32, pub num_outputs: u32, } #[derive(Encode, Decode)] -pub enum TxMetadataVersionReq { - V1(TxMetadataV1Req), -} +pub enum SignTxNextReq { + #[codec(index = 0)] + ProcessInput(Box), + + #[codec(index = 1)] + ProcessInputCommitment(Box), + #[codec(index = 2)] + ProcessOutput(Box), + + #[codec(index = 3)] + ReturnNextSignature, +} + +// Note: +// 1) `addresses` can contain multiple entries in the case of multisig or no entries at all in +// the case of a non-signable pseudo-input (at this moment FillOrder is the only possible +// pseudo-input). +// 2) Derivation paths in `addresses` are not checked against the actual destinations that the +// consensus requires the input to be signed against (note that in the non-utxo cases it's +// not really possible to verify their consistency, because we don't commit to the actual +// destination in those cases). +// This is not a problem in general, but note that since we always use SigHashType::ALL in this +// app, each input signature is a signature over the entire tx. So e.g. if inputs 0 and 1 require +// keys A and B respectively, a malfunctioning host may request input 0 to be signed with key B +// and input 1 with key A; in such a case the signature 0 will be valid for input 1 and vice versa. +// This does not allow the host to change the reviewed transaction, but it means that the app must +// not promise the user that a particular input was signed by the key specified in `addresses`. #[derive(Encode, Decode)] -pub struct TxMetadataReq { - pub coin: CoinType, - pub version: TxMetadataVersionReq, +pub struct TxInputData { + pub addresses: Vec, + pub input: TxInputWithAdditionalInfo, } #[derive(Encode, Decode)] -pub struct TxInputReq { - pub addresses: Vec, - pub inp: TxInputWithAdditionalInfo, +pub struct TxInputCommitmentData { + pub commitment: SighashInputCommitment, +} + +// TODO: +// 1) In order to be able to detect change outputs, there should be a way of specifying the destination +// via a derivation path. +// Note: the contents of Destination::PublicKeyHash and Destination::PublicKey should probably be +// enums of the form `enum PublicKeyHash { Own(derivation path), Foreign(actual hash) }`. +// 2) Possible ways of handling change outputs (simplified version of what the cardano app seems to do): +// * a) require that all derivation paths (in inputs and in outputs) belong to the same account, +// fail if they don't; +// b) if an output is a simple Transfer to a change address in the account, omit it from review; +// if it's something more complicated, don't omit it from review, but mark is as change output. +// * Same as above, but only track (without failing) whether all inputs are signed with keys from the +// same account; if so and an output is a simple Transfer to a change address in that same account, +// omit the output from review. If the output references a change address but multiple accounts +// are referenced by inputs, or if the output is not a simple Transfer, then don't omit it, +// but mark it as change. +// See https://github.com/mintlayer/mintlayer-ledger-app/issues/17. +#[derive(Encode, Decode)] +pub struct TxOutputData { + pub output: TxOutput, } #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] pub struct AdditionalOrderInfo { - pub initially_asked: mlcp::OutputValue, - pub initially_given: mlcp::OutputValue, - pub ask_balance: mlcp::Amount, - pub give_balance: mlcp::Amount, + pub initially_asked: OutputValue, + pub initially_given: OutputValue, + pub ask_balance: Amount, + pub give_balance: Amount, } #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] pub enum AdditionalUtxoInfo { - Utxo(mlcp::TxOutput), + #[codec(index = 0)] + Utxo(TxOutput), + + #[codec(index = 1)] UtxoWithPoolData { - utxo: mlcp::TxOutput, - staker_balance: mlcp::Amount, + utxo: TxOutput, + staker_balance: Amount, }, } -impl From for mlcp::SighashInputCommitment { +impl From for SighashInputCommitment { fn from(value: AdditionalUtxoInfo) -> Self { match value { - AdditionalUtxoInfo::Utxo(output) => mlcp::SighashInputCommitment::Utxo(output), + AdditionalUtxoInfo::Utxo(output) => SighashInputCommitment::Utxo(output), AdditionalUtxoInfo::UtxoWithPoolData { utxo, staker_balance, - } => mlcp::SighashInputCommitment::ProduceBlockFromStakeUtxo { + } => SighashInputCommitment::ProduceBlockFromStakeUtxo { utxo, staker_balance, }, @@ -159,59 +253,53 @@ impl From for mlcp::SighashInputCommitment { #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] pub enum TxInputWithAdditionalInfo { #[codec(index = 0)] - Utxo(mlcp::UtxoOutPoint, AdditionalUtxoInfo), + Utxo(UtxoOutPoint, AdditionalUtxoInfo), #[codec(index = 1)] - Account(mlcp::AccountOutPoint), + Account(AccountOutPoint), #[codec(index = 2)] - AccountCommand(mlcp::AccountNonce, mlcp::AccountCommand), + AccountCommand(AccountNonce, AccountCommand), #[codec(index = 3)] - OrderAccountCommand(mlcp::OrderAccountCommand, AdditionalOrderInfo), + OrderAccountCommand(OrderAccountCommand, AdditionalOrderInfo), } impl TxInputWithAdditionalInfo { - pub fn into_input_and_commitment(self) -> (mlcp::TxInput, mlcp::SighashInputCommitment) { + pub fn into_input_and_commitment(self) -> (TxInput, SighashInputCommitment) { match self { - TxInputWithAdditionalInfo::Utxo(utxo, info) => (mlcp::TxInput::Utxo(utxo), info.into()), - TxInputWithAdditionalInfo::Account(acc) => ( - mlcp::TxInput::Account(acc), - mlcp::SighashInputCommitment::None, - ), + TxInputWithAdditionalInfo::Utxo(utxo, info) => (TxInput::Utxo(utxo), info.into()), + TxInputWithAdditionalInfo::Account(acc) => { + (TxInput::Account(acc), SighashInputCommitment::None) + } TxInputWithAdditionalInfo::AccountCommand(nonce, cmd) => ( - mlcp::TxInput::AccountCommand(nonce, cmd), - mlcp::SighashInputCommitment::None, + TxInput::AccountCommand(nonce, cmd), + SighashInputCommitment::None, ), TxInputWithAdditionalInfo::OrderAccountCommand(cmd, info) => { let commitment = match &cmd { - mlcp::OrderAccountCommand::FillOrder(_, _) => { - mlcp::SighashInputCommitment::FillOrderAccountCommand { + OrderAccountCommand::FillOrder(_, _) => { + SighashInputCommitment::FillOrderAccountCommand { initially_asked: info.initially_asked, initially_given: info.initially_given, } } - mlcp::OrderAccountCommand::ConcludeOrder(_) => { - mlcp::SighashInputCommitment::ConcludeOrderAccountCommand { + OrderAccountCommand::ConcludeOrder(_) => { + SighashInputCommitment::ConcludeOrderAccountCommand { initially_asked: info.initially_asked, initially_given: info.initially_given, ask_balance: info.ask_balance, give_balance: info.give_balance, } } - mlcp::OrderAccountCommand::FreezeOrder(_) => mlcp::SighashInputCommitment::None, + OrderAccountCommand::FreezeOrder(_) => SighashInputCommitment::None, }; - (mlcp::TxInput::OrderAccountCommand(cmd), commitment) + (TxInput::OrderAccountCommand(cmd), commitment) } } } } -#[derive(Encode, Decode)] -pub struct TxOutputReq { - pub out: mlcp::TxOutput, -} - #[derive(Encode, Decode, Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive)] #[repr(u8)] pub enum CoinType { @@ -257,23 +345,23 @@ pub struct InputAddressPath { } #[derive(Encode, Decode)] -pub struct PublicKey(pub [u8; 65]); +pub struct UncompressedSecp256k1PublicKey(pub [u8; 65]); #[derive(Encode, Decode)] pub struct ChainCode(pub [u8; 32]); #[derive(Encode, Decode)] -pub struct GetPublicKeyResponse { - pub public_key: PublicKey, +pub struct PublicKeyResponse { + pub public_key: UncompressedSecp256k1PublicKey, pub chain_code: ChainCode, } #[derive(Encode, Decode)] -pub struct SignatureResponse(pub [u8; 64]); +pub struct Signature(pub [u8; 64]); #[derive(Encode, Decode)] pub struct TxInputSignatureResponse { - pub signature: SignatureResponse, + pub signature: Signature, pub input_idx: u32, pub multisig_idx: Option, pub has_next: bool, @@ -281,7 +369,7 @@ pub struct TxInputSignatureResponse { #[derive(Encode, Decode)] pub struct MsgSignatureResponse { - pub signature: SignatureResponse, + pub signature: Signature, } #[derive(Encode, Decode)] @@ -289,13 +377,13 @@ pub enum Response { #[codec(index = 0)] ExpectingNextChunk, #[codec(index = 1)] - PublicKey(GetPublicKeyResponse), + PublicKey(PublicKeyResponse), #[codec(index = 2)] TxSetup, #[codec(index = 3)] TxNext, #[codec(index = 4)] - TxSignature(TxInputSignatureResponse), + TxInputSignature(TxInputSignatureResponse), #[codec(index = 5)] MessageSetup, #[codec(index = 6)] @@ -308,16 +396,39 @@ pub fn encode(t: T) -> Vec { t.encode() } -pub fn encode_to(t: T, buf: &mut Vec) { - t.encode_to(buf) +pub fn encode_to(t: T, output: &mut O) +where + T: Encode, + O: parity_scale_codec::Output, +{ + t.encode_to(output) } -pub fn decode_all(mut bytes: &[u8]) -> Option { - T::decode_all(&mut bytes).ok() +pub fn encode_as_compact(num: N) -> Vec +where + // Note: without the Num bound, if N is a reference, the compilation would fail with + // "overflow evaluating the requirement `for<'b> CompactRef<'b, _>: Encode`". + // With the bound, the error is much clearer. + N: num_traits::Num, + N: parity_scale_codec::HasCompact, + ::Type: Encode, +{ + ::Type::from(num).encode() +} + +pub fn encode_as_compact_to(num: N, output: &mut O) +where + // Same note as in encode_as_compact. + N: num_traits::Num, + N: parity_scale_codec::HasCompact, + ::Type: Encode, + O: parity_scale_codec::Output, +{ + ::Type::from(num).encode_to(output) } -pub fn encode_as_compact(num: u32) -> Vec { - parity_scale_codec::Compact::::encode(&num.into()) +pub fn decode_all(mut bytes: &[u8]) -> Option { + T::decode_all(&mut bytes).ok() } /// This represents an APDU used in communication with Mintlayer Ledger app. @@ -340,7 +451,7 @@ impl<'a> Apdu<'a> { param1_byte: u8, command_data: &'a [u8], ) -> Option { - (command_data.len() <= MAX_ADPU_DATA_LEN).then_some(Self { + (command_data.len() <= MAX_APDU_DATA_LEN).then_some(Self { instruction_byte, param1_byte, command_data, @@ -348,20 +459,26 @@ impl<'a> Apdu<'a> { }) } - /// Returns an ExactSizeIterator of APDUs by chunking the data to MAX_ADPU_DATA_LEN + /// Returns an ExactSizeIterator of APDUs by chunking the data to MAX_APDU_DATA_LEN. pub fn new_chunks( instruction_byte: u8, param1_byte: u8, data: &'a [u8], ) -> impl ExactSizeIterator { - let chunk_iter = data.chunks(MAX_ADPU_DATA_LEN); - let last_chunk_idx = chunk_iter.len() - 1; + // Note: the standard `chunks` method returns zero-length iterator if the data has zero + // length, but we need to return 1 APDU with zero-length data in such a case. + let chunk_count = data.len().div_ceil(MAX_APDU_DATA_LEN).max(1); + let chunk_iter = (0..chunk_count).map(|i| { + let start = i * MAX_APDU_DATA_LEN; + let end = (start + MAX_APDU_DATA_LEN).min(data.len()); + &data[start..end] + }); chunk_iter.enumerate().map(move |(chunk_idx, chunk)| Self { instruction_byte, param1_byte, command_data: chunk, - is_last_chunk: chunk_idx == last_chunk_idx, + is_last_chunk: chunk_idx == chunk_count - 1, }) } @@ -428,10 +545,10 @@ pub enum StatusWord { TxLockTimeInvalid = 0xB001, #[display("Transaction wrong length")] TxWrongLength = 0xB002, - #[display("Transaction hashing failed")] - TxHashFail = 0xB003, - #[display("Transaction address failed")] - TxAddressFail = 0xB004, + #[display("Hashing failed")] + HashFail = 0xB003, + #[display("Address encoding failed")] + AddressEncodingFail = 0xB004, #[display("Different instruction than expected")] WrongInstruction = 0xB005, #[display("Key derivation failed")] @@ -448,8 +565,8 @@ pub enum StatusWord { TxNumericOperationFail = 0xB00B, #[display("Tx fee underflow")] TxFeeUnderflow = 0xB00C, - #[display("Invalid input path")] - TxInvalidInputPath = 0xB00D, + #[display("Invalid data")] + InvalidData = 0xB00D, #[display("Nothing to sign")] NothingToSign = 0xB00E, #[display("Transaction already finished")] @@ -462,8 +579,12 @@ pub enum StatusWord { MaxBufferLenExceeded = 0xB012, #[display("Different input commitment hash")] DifferentInputCommitmentHash = 0xB013, - #[display("Invalid Timestamp")] + #[display("Invalid timestamp")] InvalidTimestamp = 0xB014, + #[display("Signature for FillOrder input requested")] + FillOrderSigRequested = 0xB015, + #[display("Transaction has zero inputs")] + TxWithZeroInputs = 0xB016, // Ecc Errors #[display("ECC Carry")] diff --git a/crates/messages/src/tests.rs b/crates/messages/src/tests.rs new file mode 100644 index 0000000..aba727f --- /dev/null +++ b/crates/messages/src/tests.rs @@ -0,0 +1,74 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +use alloc::vec::Vec; + +use test_utils::prelude::*; + +use super::*; + +#[test_item] +fn test_apdu_chunking() { + let byte_iter = || core::iter::repeat(0..=9).flatten(); + + let ins = 0xaa; + let p1 = 0xbb; + + // One chunk + { + let data = byte_iter().take(100).collect::>(); + let chunks = Apdu::new_chunks(ins, p1, &data).collect::>(); + assert_eq!(chunks.len(), 1); + assert_eq!(chunks[0].instruction_byte, ins); + assert_eq!(chunks[0].param1_byte, p1); + assert_eq!(chunks[0].command_data, &data); + assert!(chunks[0].is_last_chunk); + } + + // One chunk, data is zero length + { + let chunks = Apdu::new_chunks(ins, p1, &[]).collect::>(); + assert_eq!(chunks.len(), 1); + assert_eq!(chunks[0].instruction_byte, ins); + assert_eq!(chunks[0].param1_byte, p1); + assert_eq!(chunks[0].command_data, &[]); + assert!(chunks[0].is_last_chunk); + } + + // Multiple chunks + { + let data = byte_iter().take(600).collect::>(); + let chunks = Apdu::new_chunks(ins, p1, &data).collect::>(); + + assert_eq!(chunks.len(), 3); + + assert_eq!(chunks[0].instruction_byte, ins); + assert_eq!(chunks[0].param1_byte, p1); + assert_eq!(chunks[0].command_data, &data[0..255]); + assert!(!chunks[0].is_last_chunk); + + assert_eq!(chunks[1].instruction_byte, ins); + assert_eq!(chunks[1].param1_byte, p1); + assert_eq!(chunks[1].command_data, &data[255..510]); + assert!(!chunks[1].is_last_chunk); + + assert_eq!(chunks[2].instruction_byte, ins); + assert_eq!(chunks[2].param1_byte, p1); + assert_eq!(chunks[2].command_data, &data[510..]); + assert!(chunks[2].is_last_chunk); + } +} diff --git a/crates/test-utils/Cargo.toml b/crates/test-utils/Cargo.toml new file mode 100644 index 0000000..db8b193 --- /dev/null +++ b/crates/test-utils/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "test-utils" +version.workspace = true +edition = "2024" + +[dependencies] +ledger_device_sdk = { workspace = true, features = ["unit_test"] } +testmacro.workspace = true + +[lib] +# Note: this crate doesn't have unit tests at the moment. If we ever need them, a custom runner +# has to be set up the same way it's done in `mintlayer-app-core`. For now we just disable tests +# completely to prevent Cargo from producing an uncompilable test binary. +test = false diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs new file mode 100644 index 0000000..2e33220 --- /dev/null +++ b/crates/test-utils/src/lib.rs @@ -0,0 +1,93 @@ +/***************************************************************************** + * Mintlayer Ledger App. + * (c) 2025-2026 RBB S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +//! Every crate that needs unit tests that can be run on Speculos must have the following: +//! 1. It must be a lib crate. +//! 2. At the top of its `lib.rs` specify this: +//! 1. Disable the generation of `fn main`. +//! +//! #![cfg_attr(test, no_main)] +//! +//! 2. "custom_test_frameworks" must be enabled to be able to specify the custom runner and use +//! the `#[test_case]` attribute (used internally by `testmacro::test_item`). +//! +//! #![feature(custom_test_frameworks)] +//! +//! 3. Specify the custom test runner. All test cases collected by `#[test_case]` will be passed +//! to this function. In particular, `sdk_test_runner` will loop over the array of test cases +//! and: +//! a) fix references stored inside the test case via pic_rs/pic; +//! b) invoke the closure associated with the test case. +//! +//! #![test_runner(ledger_device_sdk::testing::sdk_test_runner)] +//! +//! +//! 4. The following will put `fn test_main` at the test crate's root, which will call the runner +//! that we've specified above. The crate's `sample_main` will have to call `test_main`. +//! +//! #![reexport_test_harness_main = "test_main"] +//! 3. Under `#[cfg(test)]` call: +//! 1. test_utils::impl_panic_handler!(); +//! 2. test_utils::impl_main!(); + +#![no_std] + +extern crate alloc; + +use alloc::{borrow::ToOwned as _, format}; + +pub mod prelude { + // testmacro::test_item expects `TestType` to be imported. + pub use ledger_device_sdk::testing::TestType; + + pub use testmacro::test_item; +} + +#[macro_export] +macro_rules! impl_panic_handler { + () => { + #[panic_handler] + fn panic_handler(info: &core::panic::PanicInfo) -> ! { + test_utils::handle_panic(info) + } + }; +} + +#[allow(clippy::crate_in_macro_def)] +#[macro_export] +macro_rules! impl_main { + () => { + #[unsafe(no_mangle)] + extern "C" fn sample_main() { + crate::test_main(); + ledger_device_sdk::exit_app(0); + } + }; +} + +pub fn handle_panic(info: &core::panic::PanicInfo) -> ! { + ledger_device_sdk::error!( + "Panic occurred at {}: {}", + info.location().map_or_else( + || "???".to_owned(), + |loc| format!("{}:{}", loc.file(), loc.line()) + ), + info.message(), + ); + + ledger_device_sdk::exit_app(1); +} diff --git a/doc/mintlayer.md b/doc/mintlayer.md deleted file mode 100644 index 9dd23d9..0000000 --- a/doc/mintlayer.md +++ /dev/null @@ -1,277 +0,0 @@ -# Mintlayer application: Technical Specifications - -This page details the protocol implemented for the Mintlayer Ledger app. - -## Framework - -### APDUs - -The messaging format of the app is compatible with the standard [APDU protocol](https://developers.ledger.com/docs/device-app/explanation/io#apdu-interpretation-loop). - -The class byte used for all standard commands is `CLA = 0xE1`. - -| CLA | INS | COMMAND NAME | DESCRIPTION | -| --- | --- | -------------- | ------------------------------------------------------------------ | -| E1 | 00 | GET_PUBLIC_KEY | Return (and optionally show on screen) a public key and chain code | -| E1 | 01 | SIGN_TX | Sign a transaction through a multi-step process | -| E1 | 02 | SIGN_MSG | Sign a generic message | -| E1 | 03 | PING | Simple ping request to check connectivity | - -### Chunking and P2 - -The APDU buffer on the Ledger device has a maximum data length (`MAX_ADPU_DATA_LEN` = 255 bytes). To accommodate larger payloads, the app implements a chunking mechanism controlled by the `P2` parameter: - -- `P2 = 0x00` (`P2_DONE`): This is the final chunk (or the only chunk) of the instruction. The app will assemble the buffer and execute the command. -- `P2 = 0x80` (`P2_MORE`): More chunks follow. The app accumulates the data into a buffer (up to a maximum of `1020` bytes) and returns `0x9000` (Success) to ask the client for the next chunk. - -_Note: For chunked commands, `INS` and `P1` must remain identical across all chunks of the same sequence._ - -### Data Serialization and Responses - -The app uses **SCALE codec** (`parity_scale_codec`) for the serialization and deserialization of the data payloads. Vector length prefixes and standard variable-length integer types are represented using SCALE's Compact encoding. - -#### Response Wrapper - -On a successful command execution (returning status word `0x9000`), the app encodes the returned payload inside a top-level SCALE-encoded `Response` enum. - -The SCALE representation of an enum begins with a single byte representing the variant index, followed by the encoded fields of that variant. - -The `Response` enum structure and its variant indices are: - -| Variant Index | Variant Name | Inner Payload Type | Description | -|---|---|---|---| -| `0` | `ExpectingNextChunk` | None | Returned when more APDU chunks are expected (`P2_MORE` sequence) | -| `1` | `PublicKey` | `GetPublicKeyResponse` | Public key and chain code response | -| `2` | `TxSetup` | None | Acknowledges transaction initialization (`SIGN_TX` with `P1 = 0`) | -| `3` | `TxNext` | None | Acknowledges receipt of a transaction chunk | -| `4` | `TxSignature` | `TxInputSignatureResponse` | Contains an input signature | -| `5` | `MessageSetup` | None | Acknowledges message signing initialization (`SIGN_MSG` with `P1 = 0`) | -| `6` | `MessageSignature` | `MsgSignatureResponse` | Contains the final message signature | -| `7` | `Pong` | None | Pong response for the `PING` instruction | - -Any successful command output described below is prefixed by its corresponding 1-byte variant index. - -## Status Words - -The application returns standard Ledger status words as well as app-specific and ECC cryptographic errors. - -| SW | SW name | Description | -| ------ | ------------------------------ | ---------------------------------------------- | -| 0x5515 | `DeviceLocked` | Device locked | -| 0x6982 | `NothingReceived` | Nothing received | -| 0x6985 | `Deny` | Rejected by user / User cancelled | -| 0x6D00 | `Unknown` | Unknown | -| 0x6E00 | `ClaNotSupported` | CLA not supported | -| 0x6E01 | `InsNotSupported` | Instruction not supported | -| 0x6E02 | `WrongP1P2` | Wrong P1/P2 parameters | -| 0x6E03 | `WrongApduLength` | Wrong APDU length | -| 0x9000 | `Ok` | Success | -| 0xB000 | `TxDisplayFail` | Transaction display failed | -| 0xB001 | `TxLockTimeInvalid` | Transaction lock time value is invalid | -| 0xB002 | `TxWrongLength` | Transaction wrong length | -| 0xB003 | `TxHashFail` | Transaction hashing failed | -| 0xB004 | `TxAddressFail` | Transaction address failed | -| 0xB005 | `WrongInstruction` | Different instruction than expected | -| 0xB006 | `KeyDeriveFail` | Key derivation failed | -| 0xB007 | `OrdersV0NotSupported` | Orders V0 not supported | -| 0xB008 | `WrongContext` | Wrong context (e.g., Next called before Start) | -| 0xB009 | `DeserializeFail` | SCALE deserialization failed | -| 0xB00A | `TxInvalidInputUtxo` | Invalid input UTXO | -| 0xB00B | `TxNumericOperationFail` | Numeric operation failed | -| 0xB00C | `TxFeeUnderflow` | Tx fee underflow | -| 0xB00D | `TxInvalidInputPath` | Invalid input path | -| 0xB00E | `NothingToSign` | Nothing to sign | -| 0xB00F | `TxAlreadyFinished` | Transaction already finished | -| 0xB010 | `InvalidPath` | Invalid BIP32 path | -| 0xB011 | `InvalidUncompressedPublicKey` | Invalid uncompressed public key | -| 0xB012 | `MaxBufferLenExceeded` | Max buffer length exceeded (Chunking limit) | -| 0xB013 | `DifferentInputCommitmentHash` | Different input commitment hash | -| 0xB014 | `InvalidTimestamp` | Invalid Timestamp | -| 0xB100 | `EccCarry` | ECC Carry | -| 0xB101 | `EccLocked` | ECC Locked | -| 0xB102 | `EccUnlocked` | ECC Unlocked | -| 0xB103 | `EccNotLocked` | ECC Not Locked | -| 0xB104 | `EccNotUnlocked` | ECC Not Unlocked | -| 0xB105 | `EccInternalError` | ECC Internal Error | -| 0xB106 | `EccInvalidParameterSize` | ECC Invalid Parameter Size | -| 0xB107 | `EccInvalidParameterValue` | ECC Invalid Parameter Value | -| 0xB108 | `EccInvalidParameter` | ECC Invalid Parameter | -| 0xB109 | `EccNotInvertible` | ECC Not Invertible | -| 0xB10A | `EccOverflow` | ECC Overflow | -| 0xB10B | `EccMemoryFull` | ECC Memory Full | -| 0xB10C | `EccNoResidue` | ECC No Residue | -| 0xB10D | `EccPointAtInfinity` | ECC Point At Infinity | -| 0xB10E | `EccInvalidPoint` | ECC Invalid Point | -| 0xB10F | `EccInvalidCurve` | ECC Invalid Curve | -| 0xB110 | `EccGenericError` | ECC Generic Error | -| 0xE000 | `Panic` | Panic | - ---- - -## Commands - -### GET_PUBLIC_KEY - -Returns a public key and chain code at the given derivation path. -Optionally displays the generated address on the device screen for user verification. - -#### Encoding - -**Command** - -| _CLA_ | _INS_ | _P1_ | -| ----- | ----- | -------------------- | -| E1 | 00 | `0` or `1` (Display) | - -**Input data (`PublicKeyReq` - SCALE encoded)** - -| Type | Name | Description | -| ----------- | ----------- | --------------------------------------------------------- | -| `u8` (Enum) | `coin_type` | `0` = Mainnet, `1` = Testnet, `2` = Regtest, `3` = Signet | -| `Vec` | `path` | The BIP32 derivation path | - -**Output data (`Response::PublicKey(GetPublicKeyResponse)` - SCALE encoded)** - -| Length | Description | -| ------ | ------------------------------------------------------------------- | -| `1` | Variant index byte (`0x01`) | -| `65` | The uncompressed public key (`GetPublicKeyResponse.public_key`) | -| `32` | The chain code (`GetPublicKeyResponse.chain_code`) | - -#### Description - -If `P1` is `0`, the application derives the public key and returns it silently. -If `P1` is `1`, the application will display the address derived from the requested path on the device screen. -The command will only return `Ok` (0x9000) if the user approves it, otherwise, it returns `Deny` (0x6985). - ---- - -### SIGN_TX - -Signs a Mintlayer transaction. -Because transactions can be larger than available APDU buffers and RAM, the parsing and signing process is split into an interactive state machine using `P1 = 0` (Start) and `P1 = 1` (Next). - -#### Encoding - -**Command** - -| _CLA_ | _INS_ | _P1_ | -| ----- | ----- | ------------------------- | -| E1 | 01 | `0` (Start) or `1` (Next) | - -**Input Data for `P1 = 0` (Start) (`TxMetadataReq` - SCALE encoded)** - -| Type | Name | Description | -| ----- | ------------- | --------------------------------------------------------- | -| `u8` | `coin` | `0` = Mainnet, `1` = Testnet, `2` = Regtest, `3` = Signet | -| `u8` | `version` | Transaction version | -| `u32` | `num_inputs` | Total number of inputs in the transaction | -| `u32` | `num_outputs` | Total number of outputs in the transaction | - -**Input Data for `P1 = 1` (Next) (`SignTxReq` Enum - SCALE encoded)** - -The client sends a sequence of `SignTxReq` variants. The variant index dictates the type of data being sent: - -- `Input` (Index 0): Contains `TxInputReq` (Input address paths and UTXO/Account info). -- `InputCommitment` (Index 1): Contains `SighashInputCommitment`. -- `Output` (Index 2): Contains `TxOutputReq`. -- `NextSignature` (Index 3): Requests the device to yield the next available signature. - -**Output data (`Response::TxSignature(TxInputSignatureResponse)` - SCALE encoded)** - -Yielded during `NextSignature` sequences. - -The response payload is prefixed with the `TxSignature` variant index (`0x04`), followed by the `TxInputSignatureResponse` fields: - -| Type | Name | Description | -| ------------- | -------------- | ------------------------------------------- | -| `[u8; 64]` | `signature` | The 64-byte cryptographic signature | -| `Option` | `multisig_idx` | Optional multisig index | -| `u32` | `input_idx` | The index of the input that was just signed | -| `bool` | `has_next` | True if there are more signatures remaining | - -*Note: For `Start` (`P1 = 0`) and intermediate `Next` (`P1 = 1`) data chunks (before signatures), the app returns `Response::TxSetup` (variant index `0x02`) and `Response::TxNext` (variant index `0x03`) respectively, with no extra fields.* - -#### Description - -To sign a transaction, the client must follow a strict order: - -1. Call `SIGN_TX` with `P1 = 0` (Start) passing the overall transaction metadata (`TxMetadataReq`). -2. Sequentially call `SIGN_TX` with `P1 = 1` (Next) to stream inputs `Input`, input commitments `InputCommitment` and then outputs (`Output`). -3. After all data is verified by the user on the device's secure screen, the client requests signatures by repeatedly calling `SIGN_TX` with `P1 = 1` and the `NextSignature` variant. -4. The device will yield `TxInputSignatureResponse` payloads until `has_next` is false. - ---- - -### SIGN_MSG - -Signs a generic message using a BIP-32 derived key. The process is stateful to allow streaming long messages. - -#### Encoding - -**Command** - -| _CLA_ | _INS_ | _P1_ | -| ----- | ----- | ------------------------- | -| E1 | 02 | `0` (Start) or `1` (Next) | - -**Input Data for `P1 = 0` (Start) (`SignMessageReq` - SCALE encoded)** - -| Type | Name | Description | -| ----------- | ----------- | --------------------------------------------- | -| `u8` (Enum) | `coin` | Coin type (Mainnet, Testnet, Regtest, Signet) | -| `u8` (Enum) | `addr_type` | `0` = PublicKey, `1` = PublicKeyHash | -| `Vec` | `path` | The BIP32 derivation path to use for signing | - -**Input Data for `P1 = 1` (Next)** - -| Type | Description | -| ------------ | ------------------------------------------------------------- | -| `` | The raw byte chunks of the message payload to be accumulated. | - -**Output data (`Response::MessageSignature(MsgSignatureResponse)` - SCALE encoded)** - -The response payload is prefixed with the `MessageSignature` variant index (`0x06`), followed by the `MsgSignatureResponse` fields: - -| Length | Description | -| ------ | ----------------------------------- | -| `64` | The 64-byte cryptographic signature | - -*Note: For `Start` (`P1 = 0`) initialization, the app returns `Response::MessageSetup` (variant index `0x05`) with no extra fields.* - -#### Description - -The `SIGN_MSG` flow initializes the signing context via `Start`. -The client then sends the message chunks iteratively using `Next`. -Once the message transmission is completed and the user validates the request on the hardware screen, -the device returns the 64-byte signature. -Chunking the payload via the `P2` parameter mechanism is utilized here if the data exceeds a single APDU packet limit. - ---- - -### PING - -Simple ping request to check connectivity. - -#### Encoding - -**Command** - -| _CLA_ | _INS_ | _P1_ | -| ----- | ----- | ---- | -| E1 | 03 | `0` | - -**Input data** - -None. - -**Output data (`Response::Pong` - SCALE encoded)** - -| Length | Description | -| ------ | ----------------------------------------------------------- | -| `1` | Variant index byte (`0x07`) representing `Response::Pong` | - -#### Description - -The client sends a `PING` command to verify that the app is running and responsive. -The app returns `Response::Pong` (success indicator) on success, and returns the home screen to the user. diff --git a/docs/technical_specification.md b/docs/technical_specification.md new file mode 100644 index 0000000..7535768 --- /dev/null +++ b/docs/technical_specification.md @@ -0,0 +1,279 @@ +# Mintlayer application: Technical Specifications + +This page details the protocol implemented for the Mintlayer Ledger app. + +## Framework + +### APDUs + +The messaging format of the app is compatible with the standard [APDU protocol](https://developers.ledger.com/docs/device-app/explanation/io#apdu-interpretation-loop). + +The class byte used for all standard commands is `CLA = 0xE1`. + +| CLA | INS | COMMAND NAME | DESCRIPTION | +| --- | --- | -------------- | ------------------------------------------------------------------ | +| E1 | 00 | GET_PUBLIC_KEY | Return (and optionally show on screen) a public key and chain code | +| E1 | 01 | SIGN_TX | Sign a transaction through a multi-step process | +| E1 | 02 | SIGN_MSG | Sign a generic message | +| E1 | 03 | PING | Simple ping request to check connectivity | + +### Chunking and P2 + +The APDU buffer on the Ledger device has a maximum data length (`MAX_APDU_DATA_LEN` = 255 bytes). To accommodate larger payloads, the app implements a chunking mechanism controlled by the `P2` parameter: + +- `P2 = 0x00` (`P2_DONE`): This is the final chunk (or the only chunk) of the instruction. The app will assemble the buffer and execute the command. +- `P2 = 0x80` (`P2_MORE`): More chunks follow. The app accumulates the data into a buffer (up to a maximum of `4080` bytes) and returns SCALE-encoded `Response::ExpectingNextChunk` to ask the client for the next chunk. + +_Note: For chunked commands, `INS` and `P1` must remain identical across all chunks of the same sequence._ + +### Data Serialization and Responses + +The app uses **SCALE codec** (`parity_scale_codec`) for the serialization and deserialization of the data payloads. Vector length prefixes and standard variable-length integer types are represented using SCALE's Compact encoding. + +#### Response Wrapper + +On a successful command execution (returning status word `0x9000`), the app encodes the returned payload inside a top-level SCALE-encoded `Response` enum. + +The SCALE representation of an enum begins with a single byte representing the variant index, followed by the encoded fields of that variant. + +The `Response` enum structure and its variant indices are: + +| Index | Name | Inner Payload Type | Description | +|-------|----------------------|------------------------------|------------------------------------------------------------------------| +| `0` | `ExpectingNextChunk` | None | Returned when more APDU chunks are expected (`P2_MORE` sequence) | +| `1` | `PublicKey` | `PublicKeyResponse` | Public key and chain code response | +| `2` | `TxSetup` | None | Acknowledges transaction initialization (`SIGN_TX` with `P1 = 0`) | +| `3` | `TxNext` | None | Acknowledges receipt of a transaction chunk | +| `4` | `TxInputSignature` | `TxInputSignatureResponse` | Contains an input signature | +| `5` | `MessageSetup` | None | Acknowledges message signing initialization (`SIGN_MSG` with `P1 = 0`) | +| `6` | `MessageSignature` | `MsgSignatureResponse` | Contains the final message signature | +| `7` | `Pong` | None | Pong response for the `PING` instruction | + +Any successful command output described below is prefixed by its corresponding 1-byte variant index. + +## Status Words + +The application returns standard Ledger status words as well as app-specific and ECC cryptographic errors. + +| SW | SW name | Description | +| ------ | ------------------------------ | ---------------------------------------------- | +| 0x5515 | `DeviceLocked` | Device locked | +| 0x6982 | `NothingReceived` | Nothing received | +| 0x6985 | `Deny` | Rejected by user / User cancelled | +| 0x6D00 | `Unknown` | Unknown | +| 0x6E00 | `ClaNotSupported` | CLA not supported | +| 0x6E01 | `InsNotSupported` | Instruction not supported | +| 0x6E02 | `WrongP1P2` | Wrong P1/P2 parameters | +| 0x6E03 | `WrongApduLength` | Wrong APDU length | +| 0x9000 | `Ok` | Success | +| 0xB000 | `TxDisplayFail` | Transaction display failed | +| 0xB001 | `TxLockTimeInvalid` | Transaction lock time value is invalid | +| 0xB002 | `TxWrongLength` | Transaction wrong length | +| 0xB003 | `HashFail` | Hashing failed | +| 0xB004 | `AddressEncodingFail` | Address encoding failed | +| 0xB005 | `WrongInstruction` | Different instruction than expected | +| 0xB006 | `KeyDeriveFail` | Key derivation failed | +| 0xB007 | `OrdersV0NotSupported` | Orders V0 not supported | +| 0xB008 | `WrongContext` | Wrong context (e.g., Next called before Start) | +| 0xB009 | `DeserializeFail` | SCALE deserialization failed | +| 0xB00A | `TxInvalidInputUtxo` | Invalid input UTXO | +| 0xB00B | `TxNumericOperationFail` | Numeric operation failed | +| 0xB00C | `TxFeeUnderflow` | Tx fee underflow | +| 0xB00D | `InvalidData` | Invalid data | +| 0xB00E | `NothingToSign` | Nothing to sign | +| 0xB00F | `TxAlreadyFinished` | Transaction already finished | +| 0xB010 | `InvalidPath` | Invalid BIP32 path | +| 0xB011 | `InvalidUncompressedPublicKey` | Invalid uncompressed public key | +| 0xB012 | `MaxBufferLenExceeded` | Max buffer length exceeded (Chunking limit) | +| 0xB013 | `DifferentInputCommitmentHash` | Different input commitment hash | +| 0xB014 | `InvalidTimestamp` | Invalid timestamp | +| 0xB015 | `FillOrderSigRequested` | Signature for FillOrder input requested | +| 0xB016 | `TxWithZeroInputs` | Transaction has zero inputs | +| 0xB100 | `EccCarry` | ECC Carry | +| 0xB101 | `EccLocked` | ECC Locked | +| 0xB102 | `EccUnlocked` | ECC Unlocked | +| 0xB103 | `EccNotLocked` | ECC Not Locked | +| 0xB104 | `EccNotUnlocked` | ECC Not Unlocked | +| 0xB105 | `EccInternalError` | ECC Internal Error | +| 0xB106 | `EccInvalidParameterSize` | ECC Invalid Parameter Size | +| 0xB107 | `EccInvalidParameterValue` | ECC Invalid Parameter Value | +| 0xB108 | `EccInvalidParameter` | ECC Invalid Parameter | +| 0xB109 | `EccNotInvertible` | ECC Not Invertible | +| 0xB10A | `EccOverflow` | ECC Overflow | +| 0xB10B | `EccMemoryFull` | ECC Memory Full | +| 0xB10C | `EccNoResidue` | ECC No Residue | +| 0xB10D | `EccPointAtInfinity` | ECC Point At Infinity | +| 0xB10E | `EccInvalidPoint` | ECC Invalid Point | +| 0xB10F | `EccInvalidCurve` | ECC Invalid Curve | +| 0xB110 | `EccGenericError` | ECC Generic Error | +| 0xE000 | `Panic` | Panic | + +--- + +## Commands + +### GET_PUBLIC_KEY + +Returns a public key and chain code at the given derivation path. +Optionally displays the generated address on the device screen for user verification. + +#### Encoding + +**Command** + +| _CLA_ | _INS_ | _P1_ | +| ----- | ----- | -------------------- | +| E1 | 00 | `0` or `1` (Display) | + +**Input data (`GetPubKeyReq` - SCALE encoded)** + +| Type | Name | Description | +| ----------- | ----------- | --------------------------------------------------------- | +| `u8` (Enum) | `coin_type` | `0` = Mainnet, `1` = Testnet, `2` = Regtest, `3` = Signet | +| `Vec` | `path` | The BIP32 derivation path | + +**Output data (`Response::PublicKey(PublicKeyResponse)` - SCALE encoded)** + +| Length | Description | +| ------ | ------------------------------------------------------------------- | +| `1` | Variant index byte (`0x01`) | +| `65` | The uncompressed public key (`PublicKeyResponse.public_key`) | +| `32` | The chain code (`PublicKeyResponse.chain_code`) | + +#### Description + +If `P1` is `0`, the application derives the public key and returns it silently. +If `P1` is `1`, the application will display the address derived from the requested path on the device screen. +The command will only return `Ok` (0x9000) if the user approves it, otherwise, it returns `Deny` (0x6985). + +--- + +### SIGN_TX + +Signs a Mintlayer transaction. +Because transactions can be larger than available APDU buffers and RAM, the parsing and signing process is split into an interactive state machine using `P1 = 0` (Start) and `P1 = 1` (Next). + +#### Encoding + +**Command** + +| _CLA_ | _INS_ | _P1_ | +| ----- | ----- | ------------------------- | +| E1 | 01 | `0` (Start) or `1` (Next) | + +**Input Data for `P1 = 0` (Start) (`SignTxStartReq` - SCALE encoded)** + +| Type | Name | Description | +| ----- | ------------- | --------------------------------------------------------- | +| `u8` | `coin` | `0` = Mainnet, `1` = Testnet, `2` = Regtest, `3` = Signet | +| `u8` | `version` | Transaction version (0 = V1) | +| `u32` | `num_inputs` | Total number of inputs in the transaction | +| `u32` | `num_outputs` | Total number of outputs in the transaction | + +**Input Data for `P1 = 1` (Next) (`SignTxNextReq` Enum - SCALE encoded)** + +The client sends a sequence of `SignTxNextReq` variants. The variant index dictates the type of data being sent: + +- `ProcessInput` (Index 0): Contains `TxInputData` (input address paths and UTXO/Account info). +- `ProcessInputCommitment` (Index 1): Contains `TxInputCommitmentData`. +- `ProcessOutput` (Index 2): Contains `TxOutputData`. +- `ReturnNextSignature` (Index 3): Requests the device to yield the next available signature. + +**Output data (`Response::TxInputSignature(TxInputSignatureResponse)` - SCALE encoded)** + +Yielded during `ReturnNextSignature` sequences. + +The response payload is prefixed with the `TxInputSignature` variant index (`0x04`), followed by the `TxInputSignatureResponse` fields: + +| Type | Name | Description | +| ------------- | -------------- | ------------------------------------------- | +| `[u8; 64]` | `signature` | The 64-byte cryptographic signature | +| `u32` | `input_idx` | The index of the input that was just signed | +| `Option` | `multisig_idx` | Optional multisig index | +| `bool` | `has_next` | True if there are more signatures remaining | + +*Note: For `Start` (`P1 = 0`) and intermediate `Next` (`P1 = 1`) data chunks (before signatures), the app returns `Response::TxSetup` (variant index `0x02`) and `Response::TxNext` (variant index `0x03`) respectively, with no extra fields.* + +#### Description + +To sign a transaction, the client must follow a strict order: + +1. Call `SIGN_TX` with `P1 = 0` (Start) passing `SignTxStartReq`. +2. Sequentially call `SIGN_TX` with `P1 = 1` (Next) to stream inputs (`ProcessInput`), input commitments (`ProcessInputCommitment`) and then outputs (`ProcessOutput`). +3. After all data is verified by the user on the device's secure screen, the client requests signatures by repeatedly calling `SIGN_TX` with `P1 = 1` and the `ReturnNextSignature` variant. +4. The device will yield `TxInputSignatureResponse` payloads until `has_next` is false. + +--- + +### SIGN_MSG + +Signs a generic message using a BIP-32 derived key. + +#### Encoding + +**Command** + +| _CLA_ | _INS_ | _P1_ | +| ----- | ----- | ------------------------- | +| E1 | 02 | `0` (Start) or `1` (Next) | + +**Input Data for `P1 = 0` (Start) (`SignMessageStartReq` - SCALE encoded)** + +| Type | Name | Description | +| ----------- | ----------- | --------------------------------------------- | +| `u8` (Enum) | `coin` | Coin type (Mainnet, Testnet, Regtest, Signet) | +| `u8` (Enum) | `addr_type` | `0` = PublicKey, `1` = PublicKeyHash | +| `Vec` | `path` | The BIP32 derivation path to use for signing | + +**Input Data for `P1 = 1` (Next)** + +| Type | Description | +| ------------ | ------------------------------------------------------------- | +| `` | The raw byte chunks of the message payload to be accumulated. | + +**Output data (`Response::MessageSignature(MsgSignatureResponse)` - SCALE encoded)** + +The response payload is prefixed with the `MessageSignature` variant index (`0x06`), followed by the `MsgSignatureResponse` fields: + +| Length | Description | +| ------ | ----------------------------------- | +| `64` | The 64-byte cryptographic signature | + +*Note: For `Start` (`P1 = 0`) initialization, the app returns `Response::MessageSetup` (variant index `0x05`) with no extra fields.* + +#### Description + +The `SIGN_MSG` flow initializes the signing context via `Start`. +The client then sends the message chunks iteratively using `Next`. +Once the message transmission is completed and the user validates the request on the hardware screen, +the device returns the 64-byte signature. +Chunking the payload via the `P2` parameter mechanism is utilized here if the data exceeds a single APDU packet limit. + +--- + +### PING + +Simple ping request to check connectivity. + +#### Encoding + +**Command** + +| _CLA_ | _INS_ | _P1_ | +| ----- | ----- | ---- | +| E1 | 03 | `0` | + +**Input data** + +None. + +**Output data (`Response::Pong` - SCALE encoded)** + +| Length | Description | +| ------ | ----------------------------------------------------------- | +| `1` | Variant index byte (`0x07`) representing `Response::Pong` | + +#### Description + +The client sends a `PING` command to verify that the app is running and responsive. +The app returns `Response::Pong` (success indicator) on success, and returns the home screen to the user. diff --git a/glyphs/home_nano_nbgl.png b/media/glyphs/home_nano_nbgl.png similarity index 100% rename from glyphs/home_nano_nbgl.png rename to media/glyphs/home_nano_nbgl.png diff --git a/glyphs/mintlayer_48x48.png b/media/glyphs/mintlayer_48x48.png similarity index 100% rename from glyphs/mintlayer_48x48.png rename to media/glyphs/mintlayer_48x48.png diff --git a/glyphs/mintlayer_64x64.gif b/media/glyphs/mintlayer_64x64.gif similarity index 100% rename from glyphs/mintlayer_64x64.gif rename to media/glyphs/mintlayer_64x64.gif diff --git a/icons/mask_14x14.gif b/media/icons/mask_14x14.gif similarity index 100% rename from icons/mask_14x14.gif rename to media/icons/mask_14x14.gif diff --git a/icons/mintlayer_14x14.gif b/media/icons/mintlayer_14x14.gif similarity index 100% rename from icons/mintlayer_14x14.gif rename to media/icons/mintlayer_14x14.gif diff --git a/icons/mintlayer_32x32.gif b/media/icons/mintlayer_32x32.gif similarity index 100% rename from icons/mintlayer_32x32.gif rename to media/icons/mintlayer_32x32.gif diff --git a/icons/mintlayer_32x32.png b/media/icons/mintlayer_32x32.png similarity index 100% rename from icons/mintlayer_32x32.png rename to media/icons/mintlayer_32x32.png diff --git a/icons/mintlayer_40x40.gif b/media/icons/mintlayer_40x40.gif similarity index 100% rename from icons/mintlayer_40x40.gif rename to media/icons/mintlayer_40x40.gif diff --git a/run_extra_checks.sh b/run_extra_checks.sh index 2e4eeea..681353e 100755 --- a/run_extra_checks.sh +++ b/run_extra_checks.sh @@ -1,9 +1,16 @@ #!/bin/bash +# Run some extra checks. + set -e set -o nounset -# Run some extra checks (for now its mostly clippy). +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) + +cd "$SCRIPT_DIR" + +echo "Running codecheck.py" +python3 "tools/codecheck.py" # Notes about clippy: # 1. Ledger's guideline enforcer also runs it. But at the moment of writing this it doesn't check @@ -15,10 +22,6 @@ set -o nounset # 3. Unlike in Mintlayer Core, we can't disable certain annoying and mostly useless checks (such as # let-and-return), because the guideline enforcer will run them anyway. -SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) - -cd "$SCRIPT_DIR" - echo "Running cargo fmt" cargo fmt --check -- --config newline_style=Unix diff --git a/run_unit_tests.sh b/run_unit_tests.sh index 5f3d45c..ce503e1 100755 --- a/run_unit_tests.sh +++ b/run_unit_tests.sh @@ -3,13 +3,16 @@ set -e set -o nounset -# Run unit tests; the first argument must be the device model: nanox, nanosp, stax, flex or apex_p. +# Run unit tests. +# The first argument must be the device model: nanox, nanosp, stax, flex or apex_p. +# The second argument is optional (defaults to all) and specifies the crate whose tests must be run. SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) cd "$SCRIPT_DIR" MODEL=$1 +PACKAGE=${2:-all} if [[ "$MODEL" == "nanosp" ]]; then TARGET="nanosplus" @@ -19,11 +22,20 @@ fi echo "*** Running unit tests on $MODEL ***" -PACKAGES=(mintlayer-app-core) +if [[ "$PACKAGE" == "all" ]]; then + PACKAGES=(mintlayer-app-core mintlayer-messages) +else + PACKAGES=("$PACKAGE") +fi for package in "${PACKAGES[@]}"; do echo "*** Building unit tests for $package ***" + # Build the test with normal output and without capturing it, so that build errors, if any, + # are visible. + cargo test -p "$package" --release --no-run --target="$TARGET" + + # Build the test again using `--message-format=json`, to capture the name of the test executable. output=$(cargo test -p "$package" --release --no-run --message-format=json --target="$TARGET") jq_selector='select(.reason == "compiler-artifact") | select(.profile.test == true) | select(.executable != null) | .executable' test_exe_path=$(jq -r "$jq_selector" <<< "$output") diff --git a/src/main.rs b/src/main.rs index 1b527f4..dcf0260 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ /***************************************************************************** * Mintlayer Ledger App. * (c) 2023 Ledger SAS. - * (c) 2025 RBB S.r.l. + * (c) 2025-2026 RBB S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tests/application_client/__init__.py b/tests/application_client/__init__.py index dff703e..fbcf26c 100644 --- a/tests/application_client/__init__.py +++ b/tests/application_client/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022 RBB S.r.l +# Copyright (c) 2025-2026 RBB S.r.l # opensource@mintlayer.org # SPDX-License-Identifier: MIT # Licensed under the MIT License; @@ -28,11 +28,17 @@ def init_mintlayer_types(): "Amount": "Compact", "H256": "[u8; 32]", "BlockHeight": "Compact", + "BlockTimestamp": "Compact", "OutputValue": { "type": "enum", "type_mapping": [ ["Coin", "Amount"], - ["TokenV0", ""], # deprecated + # Note: need to have this variant to make sure TokenV1's index is 2. + # pylint: disable=fixme + # TODO: the protocol should probably not use types from mintlayer core + # primitives. + # See https://github.com/mintlayer/mintlayer-ledger-app/issues/18. + ["DeprecatedTokenV0", ""], ["TokenV1", "(TokenId, Amount)"], ], }, @@ -43,20 +49,14 @@ def init_mintlayer_types(): ["multisig_idx", "Option"], ], }, - "InputMeta": { - "type": "struct", - "type_mapping": [ - ["addresses", "Vec"], - ], - }, "Destination": { "type": "enum", "type_mapping": [ ["AnyoneCanSpend", "()"], - ["Address", "(PublicKeyHash)"], + ["PublicKeyHash", "PublicKeyHash"], ["PublicKey", "PublicKey"], ["ScriptHash", "ScriptId"], - ["ClassicMultiSig", "(PublicKeyHash)"], + ["ClassicMultisig", "PublicKeyHash"], ], }, "PublicKeyHash": "[u8; 20]", @@ -69,7 +69,7 @@ def init_mintlayer_types(): "PublicKeyHolder": { "type": "enum", "type_mapping": [ - ["Secp256k1Schnorr", "(Secp256k1PublicKey)"], + ["Secp256k1Schnorr", "Secp256k1PublicKey"], ], }, "Secp256k1PublicKey": { @@ -144,12 +144,20 @@ def init_mintlayer_types(): ["V0", "NftIssuanceV0"], ], }, + "OrderData": { + "type": "struct", + "type_mapping": [ + ["conclude_key", "Destination"], + ["ask", "OutputValue"], + ["give", "OutputValue"], + ], + }, "TxOutput": { "type": "enum", "type_mapping": [ ["Transfer", "(OutputValue, Destination)"], ["LockThenTransfer", "(OutputValue, Destination, OutputTimeLock)"], - ["Burn", "(OutputValue)"], + ["Burn", "OutputValue"], ["CreateStakePool", "(PoolId, StakePoolData)"], ["ProduceBlockFromStake", "(Destination, PoolId)"], ["CreateDelegationId", "(Destination, PoolId)"], @@ -158,6 +166,7 @@ def init_mintlayer_types(): ["IssueNft", "(TokenId, NftIssuance, Destination)"], ["DataDeposit", "Vec"], ["Htlc", "(OutputValue, HashedTimelockContract)"], + ["CreateOrder", "OrderData"], ], }, "HashedTimelockContract": { @@ -172,10 +181,10 @@ def init_mintlayer_types(): "OutputTimeLock": { "type": "enum", "type_mapping": [ - ["UntilHeight", "(BlockHeight)"], - ["UntilTime", "(BlockTimestamp)"], + ["UntilHeight", "BlockHeight"], + ["UntilTime", "BlockTimestamp"], ["ForBlockCount", "Compact"], - ["ForSeconds", "Compat"], + ["ForSeconds", "Compact"], ], }, "PoolId": "H256", @@ -185,7 +194,7 @@ def init_mintlayer_types(): "StakePoolData": { "type": "struct", "type_mapping": [ - ["value", "Amount"], + ["pledge", "Amount"], ["staker", "Destination"], ["vrf_public_key", "VRFPublicKey"], ["decommission_key", "Destination"], @@ -202,7 +211,7 @@ def init_mintlayer_types(): "VRFPublicKeyHolder": { "type": "enum", "type_mapping": [ - ["Schnorrkel", "(SchnorrkelPublicKey)"], + ["Schnorrkel", "SchnorrkelPublicKey"], ], }, "SchnorrkelPublicKey": { @@ -255,81 +264,29 @@ def init_mintlayer_types(): ["ConcludeOrder", "OrderId"], ], }, - "TxInput": { - "type": "enum", - "type_mapping": [ - ["Utxo", "OutPoint"], - ["Account", "(AccountOutPoint)"], - ["AccountCommand", "(AccountNonce, AccountCommand)"], - ["OrderAccountCommand", "OrderAccountCommand"], - ], - }, "TxInputWithAdditionalInfo": { "type": "enum", "type_mapping": [ ["Utxo", "(OutPoint, AdditionalUtxoInfo)"], - ["Account", "(AccountOutPoint)"], + ["Account", "AccountOutPoint"], ["AccountCommand", "(AccountNonce, AccountCommand)"], - ["OrderAccountCommand", "(OrderAccountCommand, AdditionalOrderInfo)"], + [ + "OrderAccountCommand", + "(OrderAccountCommand, AdditionalOrderInfo)", + ], ], }, "AccountOutPoint": { "type": "struct", "type_mapping": [ ["nonce", "Compact"], - ["account", "AccountSpending"], + ["spending", "AccountSpending"], ], }, "AccountSpending": { "type": "enum", "type_mapping": [ - ["Delegation", "(H256, Amount)"], - ], - }, - "TransactionV1": { - "type": "struct", - "type_mapping": [ - ["version", "u8"], # has to be 1 - ["flags", "Compact"], - ["inputs", "Vec"], - ["outputs", "Vec"], - ], - }, - "InputWitness": { - "type": "enum", - "type_mapping": [ - ["NoSignature", "Option>"], - ["Standard", "StandardInputSignature"], - ], - }, - "TokenAdditionalInfo": { - "type": "struct", - "type_mapping": [ - ["num_decimals", "u8"], - ["ticker", "Vec"], - ], - }, - "PoolAdditionalInfo": { - "type": "struct", - "type_mapping": [ - ["staker_balance", "Amount"], - ], - }, - "OrderAdditionalInfo": { - "type": "struct", - "type_mapping": [ - ["initially_asked", "OutputValue"], - ["initially_given", "OutputValue"], - ["ask_balance", "Amount"], - ["give_balance", "Amount"], - ], - }, - "InfoId": { - "type": "enum", - "type_mapping": [ - ["TokenId", "H256"], - ["PoolId", "H256"], - ["OrderId", "H256"], + ["DelegationBalance", "(H256, Amount)"], ], }, "SighashInputCommitment": { @@ -345,88 +302,40 @@ def init_mintlayer_types(): ], ], }, - "TxAdditionalInfo": { - "type": "struct", - "type_mapping": [ - ["token_info", "BTreeMap"], - ["pool_info", "BTreeMap"], - ["order_info", "BTreeMap"], - ], - }, - "StandardInputSignature": { - "type": "struct", - "type_mapping": [ - ["sighash_type", "u8"], - ["raw_signature", "Vec"], - ], - }, - "SignedTransaction": { + "SignTxStartReq": { "type": "struct", "type_mapping": [ - ["transaction", "TransactionV1"], - ["signatures", "Vec"], - ], - }, - "PartiallySignedTransaction": { - "type": "struct", - "type_mapping": [ - ["tx", "TransactionV1"], - ["witnesses", "Vec>"], - ["input_utxos", "Vec>"], - ["destinations", "Vec>"], - ["htlc_secrets", "Vec>"], - ["additional_infos", "TxAdditionalInfo"], - ], - }, - "SignedTransactionIntent": { - "type": "struct", - "type_mapping": [ - ["signed_message", "String"], - ["signatures", "Vec>"], - ], - }, - "AuthorizedPublicKeyHashSpend": { - "type": "struct", - "type_mapping": [ - ["public_key", "PublicKey"], - ["signature", "Signature"], - ], - }, - "TxMetadataVersionReq": { - "type": "enum", - "type_mapping": [ - ["V1", "TxMetadataV1Req"], + ["coin", "u8"], + ["version", "u8"], + ["num_inputs", "u32"], + ["num_outputs", "u32"], ], }, - "TxMetadataV1Req": { + "TxInputData": { "type": "struct", "type_mapping": [ - ["num_inputs", "u32"], - ["num_outputs", "u32"], + ["addresses", "Vec"], + ["input", "TxInputWithAdditionalInfo"], ], }, - "TxMetadataReq": { + "TxInputCommitmentData": { "type": "struct", "type_mapping": [ - ["coin", "u8"], - ["version", "TxMetadataVersionReq"], + ["commitment", "SighashInputCommitment"], ], }, - "TxInputReq": { + "UtxoWithPoolData": { "type": "struct", "type_mapping": [ - ["addresses", "Vec"], - ["inp", "TxInputWithAdditionalInfo"], + ["utxo", "TxOutput"], + ["staker_balance", "Amount"], ], }, "AdditionalUtxoInfo": { "type": "enum", "type_mapping": [ ["Utxo", "TxOutput"], - [ - "PoolInfo", - "(TxOutput, Amount)", - ], + ["UtxoWithPoolData", "UtxoWithPoolData"], ], }, "AdditionalOrderInfo": { @@ -438,318 +347,69 @@ def init_mintlayer_types(): ["give_balance", "Amount"], ], }, - "TxOutputReq": { + "TxOutputData": { "type": "struct", "type_mapping": [ - ["out", "TxOutput"], + ["output", "TxOutput"], ], }, - "SignTxReq": { + "SignTxNextReq": { "type": "enum", "type_mapping": [ - ["Input", "TxInputReq"], - ["InputCommitment", "SighashInputCommitment"], - ["Output", "TxOutputReq"], - ["NextSignature", "()"], - ], - }, - "SignatureResponse": "[u8; 64]", - "MsgSignature": { - "type": "struct", - "type_mapping": [ - ["signature", "SignatureResponse"], + ["ProcessInput", "TxInputData"], + ["ProcessInputCommitment", "TxInputCommitmentData"], + ["ProcessOutput", "TxOutputData"], + ["ReturnNextSignature", "()"], ], }, + "SignatureInResponse": "[u8; 64]", "TxInputSignatureResponse": { "type": "struct", "type_mapping": [ - ["signature", "SignatureResponse"], + ["signature", "SignatureInResponse"], ["input_idx", "u32"], ["multisig_idx", "Option"], ["has_next", "bool"], ], }, - "PublicKeyResponse": "[u8; 65]", - "ChainCodeResponse": "[u8; 32]", - "GetPublicKeyResponse": { + "UncompressedSecp256k1PublicKey": "[u8; 65]", + "ChainCode": "[u8; 32]", + "PublicKeyResponse": { "type": "struct", "type_mapping": [ - ["public_key", "PublicKeyResponse"], - ["chain_code", "ChainCodeResponse"], + ["public_key", "UncompressedSecp256k1PublicKey"], + ["chain_code", "ChainCode"], ], }, "MsgSignatureResponse": { "type": "struct", "type_mapping": [ - ["signature", "SignatureResponse"], + ["signature", "SignatureInResponse"], ], }, "Response": { "type": "enum", "type_mapping": [ ["ExpectingNextChunk", "()"], - ["PublicKey", "GetPublicKeyResponse"], + ["PublicKey", "PublicKeyResponse"], ["TxSetup", "()"], ["TxNext", "()"], - ["TxSignature", "TxInputSignatureResponse"], + ["TxInputSignature", "TxInputSignatureResponse"], ["MessageSetup", "()"], ["MessageSignature", "MsgSignatureResponse"], ["Pong", "()"], ], }, - "SemVer": { - "type": "struct", - "type_mapping": [ - ["major", "u8"], - ["minor", "u8"], - ["patch", "u16"], - ], - }, - "PeerAddressIp4": { - "type": "struct", - "type_mapping": [ - ["ip", "[u8; 4]"], - ["port", "u16"], - ], - }, - "PeerAddressIp6": { - "type": "struct", - "type_mapping": [ - ["ip", "[u8; 16]"], - ["port", "u16"], - ], - }, - "PeerAddress": { - "type": "enum", - "type_mapping": [ - ["Ip4", "PeerAddressIp4"], - ["Ip6", "PeerAddressIp6"], - ], - }, - "HandshakeHello": { - "type": "struct", - "type_mapping": [ - ["protocol", "u32"], - ["network", "[u8; 4]"], - ["services", "u64"], - ["user_agent", "String"], - ["version", "SemVer"], - ["receiver_address", "Option"], - ["current_time", "Compact"], - ["handshake_nonce", "u64"], - ], - }, - "HandshakeHelloAck": { - "type": "struct", - "type_mapping": [ - ["protocol", "u32"], - ["network", "[u8; 4]"], - ["services", "u64"], - ["user_agent", "String"], - ["version", "SemVer"], - ["receiver_address", "Option"], - ["current_time", "Compact"], - ], - }, - "HandshakeMessage": { - "type": "enum", - "type_mapping": [ - ["Hello", "HandshakeHello"], - ["HelloAck", "HandshakeHelloAck"], - ], - }, - "PingMessage": { - "type": "struct", - "type_mapping": [ - ["nonce", "u64"], - ], - }, - "BlockHeader": { - "type": "struct", - "type_mapping": [ - ["version", "u8"], - ["prev_block_id", "H256"], - ["tx_merkle_root", "H256"], - ["witness_merkle_root", "H256"], - ["timestamp", "Compact"], - ["consensus_data", "ConsensusData"], - ], - }, - "SignedBlockHeader": { - "type": "struct", - "type_mapping": [ - ["header", "BlockHeader"], - ["signature", "BlockHeaderSignature"], - ], - }, - "BlockHeaderSignature": { - "type": "enum", - "type_mapping": [ - ["None", "()"], - ["HeaderSignature", "(BlockHeaderSignatureData)"], - ], - }, - "BlockHeaderSignatureData": { - "type": "struct", - "type_mapping": [ - ["signature", "(Signature)"], - ], - }, - "Signature": { - "type": "enum", - "type_mapping": [ - ["Secp256k1Schnorr", "[u8; 64]"], - ], - }, - "ConsensusData": { - "type": "enum", - "type_mapping": [ - ["None", "()"], - ["PoW", "PoWData"], - ["PoS", "PoSData"], - ], - }, - "PoWData": { - "type": "struct", - "type_mapping": [ - ["bits", "u32"], - ["nonce", "u128"], - ], - }, - "PoSData": { - "type": "struct", - "type_mapping": [ - ["kernel_inputs", "Vec"], - ["kernel_witness", "Vec"], - ["stake_pool_id", "PoolId"], - ["vrf_data", "VRFReturn"], - ["compact_target", "u32"], - ], - }, - "VRFReturn": { - "type": "enum", - "type_mapping": [ - ["Schnorrkel", "(SchnorrkelVRFReturn)"], - ], - }, - "SchnorrkelVRFReturn": { - "type": "struct", - "type_mapping": [ - ["preout", "[u8; 32]"], - ["proof", "[u8; 64]"], - ], - }, - "BlockIdAtHeight": "H256", - "BlockBody": { - "type": "struct", - "type_mapping": [ - ["reward", "BlockReward"], - ["transactions", "Vec"], - ], - }, - "BlockReward": { - "type": "struct", - "type_mapping": [ - ["reward_outputs", "Vec"], - ], - }, - "Block": { - "type": "enum", - "type_mapping": [ - ["V1", "(BlockV1)"], - ], - }, - "BlockV1": { - "type": "struct", - "type_mapping": [ - ["header", "SignedBlockHeader"], - ["body", "BlockBody"], - ], - }, - "Id": "[u8; 32]", - "HeaderListRequest": "Vec", - "HeaderList": "Vec", - "TransactionResponse": { - "type": "enum", - "type_mapping": [ - ["not_found", "Id"], - ["found", "SignedTransaction"], - ], - }, - "Message": { - "type": "enum", - "type_mapping": [ - ["handshake", "HandshakeMessage"], - ["ping_request", "PingMessage"], - ["ping_response", "PingMessage"], - ["new_transaction", "Id"], - ["header_list_request", "HeaderListRequest"], - ["header_list", "HeaderList"], - ["block_list_request", "Vec"], - ["block_response", "()"], - ["announce_addr_request", "PeerAddress"], - ["addr_list_request", "()"], - ["addr_list_response", "Vec"], - ["transaction_request", "Id"], - ["transaction_response", "TransactionResponse"], - ], - }, - "GenerateBlockInputData": { - "type": "enum", - "type_mapping": [ - ["None", "()"], - ["PoW", "PoWGenerateBlockInputData"], - ["PoS", "PoSGenerateBlockInputData"], - ], - }, - "PoSGenerateBlockInputData": { - "type": "struct", - "type_mapping": [ - ["stake_private_key", "PrivateKey"], - ["vrf_private_key", "VRFPrivateKey"], - ["pool_id", "PoolId"], - ["kernel_inputs", "Vec"], - ["kernel_input_utxo", "Vec"], - ], - }, - "Privatekey": { - "type": "struct", - "type_mapping": [ - ["key", "PrivateKeyHolder"], - ], - }, - "PrivateKeyHolder": { - "type": "enum", - "type_mapping": [ - ["Secp256k1Schnorr", "(Secp256k1PrivateKey)"], - ], - }, - "Secp256k1PrivateKey": { - "type": "struct", - "type_mapping": [ - ["data", "[u8; 32]"], - ], - }, - "VRFPrivateKey": { - "type": "struct", - "type_mapping": [ - ["key", "VRFPrivateKeyHolder"], - ], - }, - "VRFPrivateKeyHolder": { + "TxInput": { "type": "enum", "type_mapping": [ - ["Schnorrkel", "(SchnorrkelPrivateKey)"], - ], - }, - "SchnorrkelPrivateKey": { - "type": "struct", - "type_mapping": [["key", "[u8; 64]"]], - }, - "PoWGenerateBlockInputData": { - "type": "struct", - "type_mapping": [ - ["reward_destination", "Destination"], + ["Utxo", "OutPoint"], + ["Account", "AccountOutPoint"], + ["AccountCommand", "(AccountNonce, AccountCommand)"], + [ + "OrderAccountCommand", + "OrderAccountCommand", + ], ], }, } diff --git a/tests/application_client/mintlayer_command_sender.py b/tests/application_client/mintlayer_command_sender.py index 939d5e4..529b330 100644 --- a/tests/application_client/mintlayer_command_sender.py +++ b/tests/application_client/mintlayer_command_sender.py @@ -1,55 +1,63 @@ from contextlib import contextmanager from dataclasses import dataclass from enum import IntEnum -from typing import Any, Generator, List, Optional +from typing import Generator, List import scalecodec # type: ignore from ragger.backend.interface import RAPDU, BackendInterface from ragger.navigator import NavInsID from ragger.navigator.navigation_scenario import NavigationScenarioData, UseCase -from .mintlayer_transaction import Transaction - -tx_metadata_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( - "TxMetadataReq" +from .mintlayer_response_unpacker import ( + unpack_get_public_key_response, ) -sign_tx_req_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( - "SignTxReq" +from .mintlayer_utils import ( + Transaction, + TxInputSignatureResponse, + TxInputSignature, + decode_response_variant, + sign_tx_start_req_obj, + sign_tx_next_req_obj, + verify_tx_signature, ) MAX_APDU_LEN: int = 255 -TX_RESPONSE_SIZE: int = 71 CLA: int = 0xE1 + @dataclass class ReviewTransaction: transaction: Transaction has_command_input: bool review_custom_screen_text: str + @dataclass class SignTxStep: kind: str - index: int | None = None + class GetAppAndVersionP1(IntEnum): # Parameter 1 for first APDU number. P1_START = 0x00 P1_NEXT = 0x01 + class SignTxP1(IntEnum): # Parameter 1 for first APDU number. P1_START = 0x00 P1_NEXT = 0x01 + class SignMessageP1(IntEnum): # Parameter 1 for first APDU number. P1_START = 0x00 P1_NEXT = 0x01 + class GetPublicKeyP1(IntEnum): - P1_START = 0x00 + P1_DO_NOT_CONFIRM = 0x00 # Parameter 1 for screen confirmation for GET_PUBLIC_KEY. P1_CONFIRM = 0x01 @@ -65,6 +73,7 @@ class InsType(IntEnum): GET_PUBLIC_KEY = 0x00 SIGN_TX = 0x01 SIGN_MESSAGE = 0x02 + PING = 0x03 class Errors(IntEnum): @@ -74,8 +83,8 @@ class Errors(IntEnum): SW_WRONG_P1P2 = 0x6E02 SW_WRONG_APDU_LENGTH = 0x6E03 - SW_WRONG_RESPONSE_LENGTH = 0xB000 - SW_DISPLAY_BIP32_PATH_FAIL = 0xB001 + SW_TX_DISPLAY_FAIL = 0xB000 + SW_TX_LOCK_TIME_INVALID = 0xB001 SW_WRONG_TX_LENGTH = 0xB002 SW_WRONG_CONTEXT = 0xB008 SW_DESERIALIZE_FAIL = 0xB009 @@ -83,6 +92,9 @@ class Errors(IntEnum): def split_message(message: bytes, max_size: int) -> List[bytes]: + if len(message) == 0: + return [b""] + return [message[x : x + max_size] for x in range(0, len(message), max_size)] @@ -100,12 +112,23 @@ def get_app_and_version(self) -> RAPDU: ) def get_public_key(self, coin: int, path: str) -> RAPDU: - data = coin.to_bytes(1, "little") + pack_derivation_path(path) + data = coin.to_bytes(1, "little") + pack_derivation_path_from_str(path) + + return self.backend.exchange( + cla=CLA, + ins=InsType.GET_PUBLIC_KEY, + p1=GetPublicKeyP1.P1_DO_NOT_CONFIRM, + p2=P2.P2_LAST, + data=data, + ) + + def get_public_key_by_ints_path(self, coin: int, path: list[int]) -> RAPDU: + data = coin.to_bytes(1, "little") + pack_derivation_path_from_ints(path) return self.backend.exchange( cla=CLA, ins=InsType.GET_PUBLIC_KEY, - p1=GetPublicKeyP1.P1_START, + p1=GetPublicKeyP1.P1_DO_NOT_CONFIRM, p2=P2.P2_LAST, data=data, ) @@ -114,7 +137,7 @@ def get_public_key(self, coin: int, path: str) -> RAPDU: def get_public_key_with_confirmation( self, coin: int, path: str ) -> Generator[None, None, None]: - data = coin.to_bytes(1, "little") + pack_derivation_path(path) + data = coin.to_bytes(1, "little") + pack_derivation_path_from_str(path) with self.backend.exchange_async( cla=CLA, @@ -122,8 +145,8 @@ def get_public_key_with_confirmation( p1=GetPublicKeyP1.P1_CONFIRM, p2=P2.P2_LAST, data=data, - ) as response: - yield response + ): + yield @contextmanager def sign_message( @@ -132,78 +155,96 @@ def sign_message( data = ( coin.to_bytes(1, "little") + addr_type.to_bytes(1, "little") - + pack_derivation_path(path) + + pack_derivation_path_from_str(path) ) - self.backend.exchange( - cla=CLA, ins=InsType.SIGN_MESSAGE, p1=SignMessageP1.P1_START, p2=P2.P2_LAST, data=data + response = self.backend.exchange( + cla=CLA, + ins=InsType.SIGN_MESSAGE, + p1=SignMessageP1.P1_START, + p2=P2.P2_LAST, + data=data, ) + decode_response_variant(response.data, "MessageSetup") + chunks = split_message(message, MAX_APDU_LEN) for chunk in chunks[:-1]: - self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_MESSAGE, p1=SignMessageP1.P1_NEXT, p2=P2.P2_MORE, - data=chunk + data=chunk, ) + decode_response_variant(response.data, "ExpectingNextChunk") with self.backend.exchange_async( cla=CLA, ins=InsType.SIGN_MESSAGE, p1=SignMessageP1.P1_NEXT, p2=P2.P2_LAST, - data=chunks[-1] - ) as response: - yield response + data=chunks[-1], + ): + yield + # pylint: disable-next=too-many-locals def sign_tx(self, transaction: Transaction) -> Generator[SignTxStep, None, None]: - # ---- METADATA ---- - metadata = tx_metadata_obj.encode( + # ---- Start req ---- + start_req = sign_tx_start_req_obj.encode( { "coin": transaction.coin, - "version": { - "V1": { - "num_inputs": len(transaction.inputs), - "num_outputs": len(transaction.outputs), - }, - }, + "version": 0, + "num_inputs": len(transaction.inputs), + "num_outputs": len(transaction.outputs), } ).data - res = self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_START, p2=P2.P2_LAST, - data=bytes(metadata), + data=bytes(start_req), ) - print("metadata ", res) + decode_response_variant(response.data, "TxSetup") # ---- INPUTS ---- print("sending inputs", len(transaction.inputs)) + def encode_input(inp): + return sign_tx_next_req_obj.encode({"ProcessInput": inp}).data + + def encode_input_comm(comm): + return sign_tx_next_req_obj.encode({"ProcessInputCommitment": comm}).data + + def encode_output(outp): + return sign_tx_next_req_obj.encode({"ProcessOutput": outp}).data + for inp in transaction.inputs: - self._send_chunked_sync(inp) + encoded_inp = encode_input(inp) + self._send_chunked_sync(encoded_inp, "TxNext") # ---- INPUT COMMITMENTS ---- print("sending input commitments") - for inp in transaction.input_commitments[:-1]: - self._send_chunked_sync(inp) + for comm in transaction.input_commitments[:-1]: + encoded_comm = encode_input_comm(comm) + self._send_chunked_sync(encoded_comm, "TxNext") - chunks = split_message(transaction.input_commitments[-1], MAX_APDU_LEN) + encoded_comm = encode_input_comm(transaction.input_commitments[-1]) + chunks = split_message(encoded_comm, MAX_APDU_LEN) # all but last chunk sync for chunk in chunks[:-1]: - self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_MORE, data=chunk, ) + decode_response_variant(response.data, "ExpectingNextChunk") # last chunk async -> UI review with self.backend.exchange_async( @@ -213,9 +254,13 @@ def sign_tx(self, transaction: Transaction) -> Generator[SignTxStep, None, None] p2=P2.P2_LAST, data=chunks[-1], ): - kind = "start" - yield SignTxStep(kind=kind, index=0) + yield SignTxStep(kind="start") + + if len(transaction.outputs) == 0: + yield SignTxStep(kind="sign") + response = self.get_async_response() + decode_response_variant(response.data, "TxNext") # ---- OUTPUTS ---- print("streaming outputs") @@ -223,17 +268,19 @@ def sign_tx(self, transaction: Transaction) -> Generator[SignTxStep, None, None] for idx, out in enumerate(transaction.outputs): print(f"sending output {idx}") - chunks = split_message(out, MAX_APDU_LEN) + encoded_out = encode_output(out) + chunks = split_message(encoded_out, MAX_APDU_LEN) # all but last chunk sync for chunk in chunks[:-1]: - self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_MORE, data=chunk, ) + decode_response_variant(response.data, "ExpectingNextChunk") # last chunk async -> UI review with self.backend.exchange_async( @@ -243,39 +290,45 @@ def sign_tx(self, transaction: Transaction) -> Generator[SignTxStep, None, None] p2=P2.P2_LAST, data=chunks[-1], ): - kind = "final" if idx == len(transaction.outputs) - 1 else "output" - yield SignTxStep(kind=kind, index=idx) + kind = "sign" if idx == len(transaction.outputs) - 1 else "output" + yield SignTxStep(kind=kind) - def _send_chunked_sync(self, data: bytes): + response = self.get_async_response() + decode_response_variant(response.data, "TxNext") + + def _send_chunked_sync(self, data: bytes, expected_last_response_variant: str): chunks = split_message(data, MAX_APDU_LEN) for chunk in chunks[:-1]: - self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_MORE, data=chunk, ) + decode_response_variant(response.data, "ExpectingNextChunk") - self.backend.exchange( + response = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_LAST, data=chunks[-1], ) + return decode_response_variant(response.data, expected_last_response_variant) - def get_async_response(self) -> Optional[RAPDU]: - return self.backend.last_async_response + def get_async_response(self) -> RAPDU: + response = self.backend.last_async_response + assert response is not None + return response - def get_all_signatures(self, tx: Transaction) -> List[bytes | Any]: - if self.backend.last_async_response is None: - raise ValueError("None response") + def get_all_signatures(self, transaction: Transaction) -> List[TxInputSignature]: + next_sig = sign_tx_next_req_obj.encode({"ReturnNextSignature": None}).data + sigs = [] + expected_sigs_count = len(transaction.expected_sig_indices()) - next_sig = sign_tx_req_obj.encode({"NextSignature": None}).data - responses = [self.backend.last_async_response.data] - for _ in tx.inputs[1:]: + while True: res = self.backend.exchange( cla=CLA, ins=InsType.SIGN_TX, @@ -283,37 +336,53 @@ def get_all_signatures(self, tx: Transaction) -> List[bytes | Any]: p2=P2.P2_LAST, data=next_sig, ) - if res is not None: - responses.append(res.data) - else: - raise ValueError("None response") - return responses + res = TxInputSignatureResponse.from_data(res.data) + + sigs.append(TxInputSignature.from_response(res)) + + if not res.has_next: + break + + assert len(sigs) < expected_sigs_count, ( + "has_next is still true after the expected number of signatures " + f"have been received (sigs = {sigs!r})" + ) + return sigs def hardened_index(index: int) -> int: return index | 1 << 31 -def pack_derivation_path(derivation_path: str) -> bytes: - path_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("Bip32Path") - +def parse_derivation_path(derivation_path: str) -> list[int]: split = derivation_path.split("/") if split[0] != "m": raise ValueError("Error master expected") - path = [] + result = [] for value in split[1:]: if value == "": raise ValueError(f'Error missing value in split list "{split}"') if value.endswith("'"): - path.append(hardened_index(int(value[:-1]))) + result.append(hardened_index(int(value[:-1]))) else: - path.append(int(value)) + result.append(int(value)) + + return result + + +def pack_derivation_path_from_str(path: str) -> bytes: + parsed_path = parse_derivation_path(path) + return pack_derivation_path_from_ints(parsed_path) + +def pack_derivation_path_from_ints(path: list[int]) -> bytes: + path_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("Bip32Path") return path_obj.encode(path).data +# pylint: disable-next=too-many-locals,too-many-branches,too-many-statements def sign_tx_review( client, device, @@ -325,13 +394,26 @@ def sign_tx_review( has_command_input = review_transaction.has_command_input review_custom_screen_text = review_transaction.review_custom_screen_text + addr_paths_by_indices = transaction.addr_paths_by_indices() + pubkeys_by_indices = {} + for indices, addr_path in addr_paths_by_indices.items(): + pubkey_rapdu = client.get_public_key_by_ints_path(transaction.coin, addr_path) + _, pubkey, _, _ = unpack_get_public_key_response(pubkey_rapdu.data) + + pubkeys_by_indices[indices] = pubkey + + # The snapshot index (used to make its name) and the amount by which it should be increased + # after each step. The increase should be large enough, so that snapshots from later steps + # don't overwrite the previous ones (10 is not enough). start_idx = 0 + idx_inc = 100 + if not device.is_nano: instruction = NavInsID.SWIPE_CENTER_TO_LEFT else: instruction = NavInsID.RIGHT_CLICK - last_page_pattern=r".*\((\d+)/\1\)$" + last_page_pattern = r".*\((\d+)/\1\)$" for step in client.sign_tx(transaction): print("step kind: ", step.kind) @@ -344,7 +426,7 @@ def sign_tx_review( screen_change_after_last_instruction=False, snap_start_idx=start_idx, ) - start_idx += 10 + start_idx += idx_inc if has_command_input: if device.is_nano: @@ -367,7 +449,7 @@ def sign_tx_review( screen_change_after_last_instruction=False, snap_start_idx=start_idx, ) - start_idx += 10 + start_idx += idx_inc if step.kind == "output": if device.is_nano: @@ -390,27 +472,63 @@ def sign_tx_review( screen_change_after_last_instruction=False, snap_start_idx=start_idx, ) - start_idx += 10 + start_idx += idx_inc - elif step.kind == "final": + elif step.kind == "sign": scenario = NavigationScenarioData( scenario_navigator.device, scenario_navigator.backend, UseCase.TX_REVIEW, - True) + True, + ) + + if device.is_nano: + validation_instructions = scenario.validation + else: + # On touch devices `UseCase.TX_REVIEW` sets `scenario.validation` to + # `[USE_CASE_REVIEW_CONFIRM, USE_CASE_STATUS_DISMISS]`. But the status screen + # appears only after the last `ReturnNextSignature`. + validation_instructions = [NavInsID.USE_CASE_REVIEW_CONFIRM] + navigator.navigate_until_text_and_compare( navigate_instruction=scenario.navigation, - validation_instructions=scenario.validation, + validation_instructions=validation_instructions, text=review_custom_screen_text, path=scenario_navigator.screenshot_path, test_case_name=scenario_navigator.test_name, screen_change_after_last_instruction=False, snap_start_idx=start_idx, - ) - - # The device as yielded the result, parse it and ensure that the signature is correct - responses = client.get_all_signatures(transaction) - - assert len(responses) == len(transaction.inputs) - for response in responses: - assert len(response) == TX_RESPONSE_SIZE + ) + start_idx += idx_inc + + # After review approval, explicitly request every signature. + signatures = client.get_all_signatures(transaction) + + # The last ReturnNextSignature is what makes the tx Finished, so the "Transaction signed" + # status screen is expected here. + validation_instructions = ( + [] if device.is_nano else [NavInsID.USE_CASE_STATUS_DISMISS] + ) + navigator.navigate_until_text_and_compare( + navigate_instruction=NavInsID.WAIT_FOR_SCREEN_CHANGE, + validation_instructions=validation_instructions, + text=r"^Transaction signed$", + path=scenario_navigator.screenshot_path, + test_case_name=scenario_navigator.test_name, + screen_change_before_first_instruction=False, + screen_change_after_last_instruction=False, + snap_start_idx=start_idx, + ) + + sig_indices = {sig.indices() for sig in signatures} + expected_sig_indices = transaction.expected_sig_indices() + assert ( + sig_indices == expected_sig_indices + ), f"Sig indices don't match, expected: {expected_sig_indices}, actual: {sig_indices}" + + addr_paths_by_indices = transaction.addr_paths_by_indices() + + for sig in signatures: + pubkey = pubkeys_by_indices[sig.indices()] + sig_valid = verify_tx_signature(transaction, pubkey, sig.signature) + assert sig_valid, f"Signature verification failed for {sig.indices()}" diff --git a/tests/application_client/mintlayer_response_unpacker.py b/tests/application_client/mintlayer_response_unpacker.py index edb28d4..2f30f24 100644 --- a/tests/application_client/mintlayer_response_unpacker.py +++ b/tests/application_client/mintlayer_response_unpacker.py @@ -1,7 +1,7 @@ from struct import unpack from typing import Tuple -import scalecodec # type: ignore +from .mintlayer_utils import decode_response_variant # remainder, data_len, data @@ -52,17 +52,12 @@ def unpack_get_app_and_version_response(response: bytes) -> Tuple[str, str]: # Unpack from response: def unpack_get_public_key_response(response: bytes) -> Tuple[int, bytes, int, bytes]: - response_bytes = scalecodec.base.ScaleBytes(response) - response_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( - "Response", data=response_bytes - ) - msg = response_obj.decode() - + msg = decode_response_variant(response, "PublicKey") print(msg) - pub_key = bytes.fromhex(msg["PublicKey"]["public_key"][2:]) + pub_key = bytes.fromhex(msg["public_key"][2:]) pub_key_len = len(pub_key) - chain_code = bytes.fromhex(msg["PublicKey"]["chain_code"][2:]) + chain_code = bytes.fromhex(msg["chain_code"][2:]) chain_code_len = len(chain_code) print(pub_key_len, pub_key) @@ -75,12 +70,7 @@ def unpack_get_public_key_response(response: bytes) -> Tuple[int, bytes, int, by # Unpack from response: def unpack_sign_message_response(response: bytes) -> bytes: - response_bytes = scalecodec.base.ScaleBytes(response) - response_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( - "Response", data=response_bytes - ) - resp = response_obj.decode() - assert resp["MessageSignature"] is not None - signature = bytes.fromhex(resp["MessageSignature"]["signature"][2:]) + resp = decode_response_variant(response, "MessageSignature") + signature = bytes.fromhex(resp["signature"][2:]) assert len(signature) == 64 return signature diff --git a/tests/application_client/mintlayer_transaction.py b/tests/application_client/mintlayer_transaction.py deleted file mode 100644 index acd6ac1..0000000 --- a/tests/application_client/mintlayer_transaction.py +++ /dev/null @@ -1,14 +0,0 @@ -from dataclasses import dataclass -from typing import List - - -class TransactionError(Exception): - pass - - -@dataclass -class Transaction: - coin: int - inputs: List[bytes] - input_commitments: List[bytes] - outputs: List[bytes] diff --git a/tests/application_client/mintlayer_utils.py b/tests/application_client/mintlayer_utils.py index fd96e62..ebd1220 100644 --- a/tests/application_client/mintlayer_utils.py +++ b/tests/application_client/mintlayer_utils.py @@ -1,61 +1,201 @@ -from io import BytesIO -from typing import Optional, Literal +from dataclasses import dataclass +from hashlib import blake2b +from typing import List, Optional + +from coincurve import PublicKeyXOnly +import scalecodec # type: ignore + +sign_tx_start_req_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( + "SignTxStartReq" +) +sign_tx_next_req_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( + "SignTxNextReq" +) +compact_u32_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( + "Compact" +) +tx_input_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("TxInput") +tx_input_commitment_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( + "SighashInputCommitment" +) +tx_output_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("TxOutput") + + +@dataclass +class TxInputSignatureResponse: + signature: bytes + input_idx: int + multisig_idx: Optional[int] + has_next: bool + + @staticmethod + def from_data(response: bytes): + decoded_response = decode_response_variant(response, "TxInputSignature") + + signature = bytes.fromhex(decoded_response["signature"][2:]) + assert len(signature) == 64 + + return TxInputSignatureResponse( + signature=signature, + input_idx=decoded_response["input_idx"], + multisig_idx=decoded_response["multisig_idx"], + has_next=decoded_response["has_next"], + ) + + +@dataclass(frozen=True) +class TxInputSignatureIndices: + input_idx: int + multisig_idx: Optional[int] + + +@dataclass +class TxInputSignature: + signature: bytes + input_idx: int + multisig_idx: Optional[int] + + @staticmethod + def from_response(response: TxInputSignatureResponse): + return TxInputSignature( + signature=response.signature, + input_idx=response.input_idx, + multisig_idx=response.multisig_idx, + ) + + def indices(self) -> TxInputSignatureIndices: + return TxInputSignatureIndices( + input_idx=self.input_idx, + multisig_idx=self.multisig_idx, + ) + + +@dataclass +class Transaction: + coin: int + # A list of TxInputData objects. + inputs: List[dict] + # A list of TxInputCommitmentData objects. + input_commitments: List[dict] + # A list of TxOutputData objects. + outputs: List[dict] + + # Extract key derivation path for each input_idx/multisig_idx combination + # and return it as a dict. + def addr_paths_by_indices(self) -> dict[TxInputSignatureIndices, list[int]]: + result = {} + for input_idx, inp in enumerate(self.inputs): + for addr in inp["addresses"]: + multisig_idx = addr["multisig_idx"] + indices = TxInputSignatureIndices( + input_idx=input_idx, multisig_idx=multisig_idx + ) + + result[indices] = addr["path"] + + return result + + def expected_sig_indices(self) -> set[TxInputSignatureIndices]: + return set(self.addr_paths_by_indices()) + + def digest_for_signing(self) -> bytes: + encoded_inputs = b"" + for inp_data in self.inputs: + inp_with_info = inp_data["input"] + if "Utxo" in inp_with_info: + inp = {"Utxo": inp_with_info["Utxo"][0]} + elif "Account" in inp_with_info: + inp = {"Account": inp_with_info["Account"]} + elif "AccountCommand" in inp_with_info: + inp = {"AccountCommand": inp_with_info["AccountCommand"]} + elif "OrderAccountCommand" in inp_with_info: + inp = {"OrderAccountCommand": inp_with_info["OrderAccountCommand"][0]} + else: + raise ValueError("Unexpected input") + + encoded_inputs += tx_input_obj.encode(inp).data + + encoded_input_commitments = b"" + for inp_comm in self.input_commitments: + comm = inp_comm["commitment"] + encoded_input_commitments += tx_input_commitment_obj.encode(comm).data + + encoded_outputs = b"" + for outp_data in self.outputs: + outp = outp_data["output"] + encoded_outputs += tx_output_obj.encode(outp).data + + assert len(self.input_commitments) == len(self.inputs) + + num_inputs_as_le_bytes = len(self.inputs).to_bytes(4, "little") + compact_encoded_num_outputs = compact_u32_obj.encode(len(self.outputs)).data + + preimage = ( + b"\x01" # SigHashType::ALL + + b"\x01" # version + + bytes(16) # zero flags + + num_inputs_as_le_bytes + + encoded_inputs + + num_inputs_as_le_bytes + + encoded_input_commitments + + compact_encoded_num_outputs + + encoded_outputs + ) + + tx_hash = mintlayer_hash(mintlayer_hash(preimage)) + return tx_hash + + +def decode_response(response: bytes) -> dict: + response_bytes = scalecodec.base.ScaleBytes(response) + response_obj = scalecodec.base.RuntimeConfiguration().create_scale_object( + "Response", data=response_bytes + ) + return response_obj.decode() + + +def decode_response_variant(response: bytes, expected_variant: str) -> dict: + decoded_response = decode_response(response) + + assert ( + isinstance(decoded_response, dict) + and len(decoded_response) == 1 + and expected_variant in decoded_response + ), f"Expecting a dict with a single key '{expected_variant}', but got: {decoded_response!r}" + + return decoded_response[expected_variant] + + +def mintlayer_hash(data: bytes) -> bytes: + return blake2b(data, digest_size=64).digest()[:32] -UINT64_MAX: int = 2**64-1 -UINT32_MAX: int = 2**32-1 -UINT16_MAX: int = 2**16-1 +MESSAGE_MAGIC_PREFIX = b"===MINTLAYER MESSAGE BEGIN===\n" +MESSAGE_MAGIC_SUFFIX = b"\n===MINTLAYER MESSAGE END===" + + +def mintlayer_message_digest(message: bytes) -> bytes: + framed = MESSAGE_MAGIC_PREFIX + message + MESSAGE_MAGIC_SUFFIX + return mintlayer_hash(mintlayer_hash(framed)) + +def xonly_pubkey(public_key: bytes) -> bytes: + if len(public_key) == 32: + return public_key + if len(public_key) == 33 and public_key[0] in (0x02, 0x03): + return public_key[1:33] + if len(public_key) == 65 and public_key[0] == 0x04: + return public_key[1:33] + raise ValueError( + "Expected x-only, compressed, or uncompressed secp256k1 public key" + ) -def write_varint(n: int) -> bytes: - if n < 0xFC: - return n.to_bytes(1, byteorder="little") - if n <= UINT16_MAX: - return b"\xFD" + n.to_bytes(2, byteorder="little") +def verify_message_signature(msg: bytes, pubkey: bytes, sig: bytes) -> bool: + digest = mintlayer_message_digest(msg) + return PublicKeyXOnly(xonly_pubkey(pubkey)).verify(sig, digest) - if n <= UINT32_MAX: - return b"\xFE" + n.to_bytes(4, byteorder="little") - if n <= UINT64_MAX: - return b"\xFF" + n.to_bytes(8, byteorder="little") - - raise ValueError(f"Can't write to varint: '{n}'!") - - -def read_varint(buf: BytesIO, - prefix: Optional[bytes] = None) -> int: - b: bytes = prefix if prefix else buf.read(1) - - if not b: - raise ValueError(f"Can't read prefix: '{b.hex()}'!") - - n: int = {b"\xfd": 2, b"\xfe": 4, b"\xff": 8}.get(b, 1) # default to 1 - - b = buf.read(n) if n > 1 else b - - if len(b) != n: - raise ValueError("Can't read varint!") - - return int.from_bytes(b, byteorder="little") - - -def read(buf: BytesIO, size: int) -> bytes: - b: bytes = buf.read(size) - - if len(b) < size: - raise ValueError(f"Can't read {size} bytes in buffer!") - - return b - - -def read_uint(buf: BytesIO, - bit_len: int, - byteorder: Literal['big', 'little'] = 'little') -> int: - size: int = bit_len // 8 - b: bytes = buf.read(size) - - if len(b) < size: - raise ValueError(f"Can't read u{bit_len} in buffer!") - - return int.from_bytes(b, byteorder) +def verify_tx_signature(tx: Transaction, pubkey: bytes, sig: bytes) -> bool: + digest = tx.digest_for_signing() + return PublicKeyXOnly(xonly_pubkey(pubkey)).verify(sig, digest) diff --git a/tests/boil-freeze.txt b/tests/boil-freeze.txt deleted file mode 100644 index a74fc92..0000000 --- a/tests/boil-freeze.txt +++ /dev/null @@ -1,60 +0,0 @@ -aniso8601==9.0.1 -asn1crypto==1.5.1 -attrs==22.2.0 -bip-utils==2.7.0 -cbor2==5.4.6 -certifi==2022.12.7 -cffi==1.15.1 -charset-normalizer==3.0.1 -click==8.1.3 -coincurve==17.0.0 -construct==2.10.68 -crcmod==1.7 -cryptography==39.0.1 -ecdsa==0.16.1 -ed25519-blake2b==1.4 -exceptiongroup==1.1.0 -Flask==2.1.2 -Flask-RESTful==0.3.9 -hidapi==0.13.1 -idna==3.4 -importlib-metadata==6.0.0 -importlib-resources==5.12.0 -iniconfig==2.0.0 -intelhex==2.3.0 -itsdangerous==2.1.2 -Jinja2==3.1.2 -jsonschema==4.17.3 -ledgerwallet==0.2.3 -MarkupSafe==2.1.2 -mnemonic==0.20 -packaging==23.0 -Pillow==9.4.0 -pkg_resources==0.0.0 -pkgutil_resolve_name==1.3.10 -pluggy==1.0.0 -protobuf==3.20.3 -py-sr25519-bindings==0.1.4 -pycparser==2.21 -pycryptodome==3.17 -pyelftools==0.29 -PyNaCl==1.5.0 -PyQt5==5.15.9 -PyQt5-Qt5==5.15.2 -PyQt5-sip==12.11.1 -pyrsistent==0.19.3 -pysha3==1.0.2 -pytesseract==0.3.10 -pytest==7.2.1 -pytz==2022.7.1 -ragger==1.6.0 -requests==2.28.2 -semver==2.13.0 -six==1.16.0 -speculos==0.1.224 -tabulate==0.9.0 -toml==0.10.2 -tomli==2.0.1 -urllib3==1.26.14 -Werkzeug==2.2.3 -zipp==3.15.0 diff --git a/tests/regenerate_snapshots.sh b/tests/regenerate_snapshots.sh new file mode 100755 index 0000000..fce36e4 --- /dev/null +++ b/tests/regenerate_snapshots.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e +set -o nounset + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +SNAPSHOTS_DIR=$SCRIPT_DIR/snapshots +ROOT_DIR=$(cd "$SCRIPT_DIR/.." && pwd) + +MODELS=(nanox nanosp stax flex apex_p) + +cd "$ROOT_DIR" + +echo "*** Removing old snapshots ***" +rm -rf "$SNAPSHOTS_DIR" + +for model in "${MODELS[@]}"; do + if [[ "$model" == "nanosp" ]]; then + TARGET="nanosplus" + else + TARGET="$model" + fi + + # Clean the build directory. Note that most of the time this is redundant, but after + # the app version has been bumped this is actually needed, otherwise the old version + # may be picked up from the existing artifacts of the sdk's build script. + echo "*** Cleaning the build directory for $model ***" + cargo clean --target "$TARGET" + + echo "*** Building the app for $model ***" + cargo ledger build "$TARGET" + + echo "*** Regenerating snapshots for $model ***" + pytest tests/ --tb=short -v --device "$model" --golden_run +done diff --git a/tests/requirements.txt b/tests/requirements.txt index fdc689b..1c7e6e3 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,6 +1,4 @@ +coincurve>=20.0.0 pytest ragger[speculos,ledgerwallet]>=1.21.1 -ecdsa>=0.16.1,<0.17.0 -safe-pysha3>=1.0.0,<2.0.0 -tomli>=2.0.1 -scalecodec>=1.2.11 \ No newline at end of file +scalecodec>=1.2.11 diff --git a/tests/snapshots/apex_p/test_app_mainmenu/00001.png b/tests/snapshots/apex_p/test_app_mainmenu/00001.png index fff0d0d..650255f 100644 Binary files a/tests/snapshots/apex_p/test_app_mainmenu/00001.png and b/tests/snapshots/apex_p/test_app_mainmenu/00001.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00000.png b/tests/snapshots/apex_p/test_sign_large_message/00000.png new file mode 100644 index 0000000..b5959c6 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00001.png b/tests/snapshots/apex_p/test_sign_large_message/00001.png new file mode 100644 index 0000000..6c4faa0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00001.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00002.png b/tests/snapshots/apex_p/test_sign_large_message/00002.png new file mode 100644 index 0000000..4b0c35c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00002.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00003.png b/tests/snapshots/apex_p/test_sign_large_message/00003.png new file mode 100644 index 0000000..857f887 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00003.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00004.png b/tests/snapshots/apex_p/test_sign_large_message/00004.png new file mode 100644 index 0000000..d0ceff0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00004.png differ diff --git a/tests/snapshots/apex_p/test_sign_large_message/00005.png b/tests/snapshots/apex_p/test_sign_large_message/00005.png new file mode 100644 index 0000000..5784e46 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_large_message/00005.png differ diff --git a/tests/snapshots/apex_p/test_sign_message/00000.png b/tests/snapshots/apex_p/test_sign_message/00000.png index 16b258a..be2479e 100644 Binary files a/tests/snapshots/apex_p/test_sign_message/00000.png and b/tests/snapshots/apex_p/test_sign_message/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_message_pkh/00000.png b/tests/snapshots/apex_p/test_sign_message_pkh/00000.png index 16b258a..be2479e 100644 Binary files a/tests/snapshots/apex_p/test_sign_message_pkh/00000.png and b/tests/snapshots/apex_p/test_sign_message_pkh/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_message_refused/00000.png b/tests/snapshots/apex_p/test_sign_message_refused/00000.png index 16b258a..be2479e 100644 Binary files a/tests/snapshots/apex_p/test_sign_message_refused/00000.png and b/tests/snapshots/apex_p/test_sign_message_refused/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00020.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00020.png deleted file mode 100644 index bad1ebd..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00023.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00010.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_authority/00010.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_authority/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00011.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_authority/00011.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_authority/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00200.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00200.png new file mode 100644 index 0000000..d019bb5 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00021.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_authority/00021.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_authority/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00022.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_authority/00022.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_authority/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_delegation/00013.png b/tests/snapshots/apex_p/test_sign_tx_change_token_authority/00300.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_delegation/00013.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_authority/00300.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00020.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00020.png deleted file mode 100644 index bad1ebd..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00023.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00010.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00010.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00011.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00011.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00200.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00200.png new file mode 100644 index 0000000..d019bb5 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00021.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00021.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00022.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00022.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00013.png b/tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00300.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00013.png rename to tests/snapshots/apex_p/test_sign_tx_change_token_metadata_uri/00300.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_delegation/00010.png b/tests/snapshots/apex_p/test_sign_tx_create_delegation/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_delegation/00010.png rename to tests/snapshots/apex_p/test_sign_tx_create_delegation/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_delegation/00011.png b/tests/snapshots/apex_p/test_sign_tx_create_delegation/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_delegation/00011.png rename to tests/snapshots/apex_p/test_sign_tx_create_delegation/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_delegation/00012.png b/tests/snapshots/apex_p/test_sign_tx_create_delegation/00102.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_delegation/00012.png rename to tests/snapshots/apex_p/test_sign_tx_create_delegation/00102.png diff --git a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00013.png b/tests/snapshots/apex_p/test_sign_tx_create_delegation/00200.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_delegation_staking/00013.png rename to tests/snapshots/apex_p/test_sign_tx_create_delegation/00200.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00010.png b/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00010.png rename to tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00011.png b/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00011.png rename to tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00012.png b/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00102.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00012.png rename to tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00102.png diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00023.png b/tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00200.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_htlc/00023.png rename to tests/snapshots/apex_p/test_sign_tx_create_stake_pool/00200.png diff --git a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00000.png b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00000.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_delegation_staking/00000.png rename to tests/snapshots/apex_p/test_sign_tx_delegate_staking/00000.png diff --git a/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00100.png b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00100.png new file mode 100644 index 0000000..5a6372a Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00011.png b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_delegation_staking/00011.png rename to tests/snapshots/apex_p/test_sign_tx_delegate_staking/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00102.png b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00102.png new file mode 100644 index 0000000..f471ae0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00102.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00013.png b/tests/snapshots/apex_p/test_sign_tx_delegate_staking/00200.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00013.png rename to tests/snapshots/apex_p/test_sign_tx_delegate_staking/00200.png diff --git a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00010.png b/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00010.png deleted file mode 100644 index b3ab59b..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00012.png b/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00012.png deleted file mode 100644 index c5cae15..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_delegation_staking/00012.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00020.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00020.png deleted file mode 100644 index bad1ebd..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00023.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00010.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00010.png rename to tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00011.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00011.png rename to tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00200.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00200.png new file mode 100644 index 0000000..d019bb5 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00021.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00021.png rename to tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00022.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00022.png rename to tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00013.png b/tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00300.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_nft/00013.png rename to tests/snapshots/apex_p/test_sign_tx_freeze_tokens/00300.png diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00020.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00020.png deleted file mode 100644 index c2afd83..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_htlc/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00010.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_htlc/00010.png rename to tests/snapshots/apex_p/test_sign_tx_htlc/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00011.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_htlc/00011.png rename to tests/snapshots/apex_p/test_sign_tx_htlc/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00200.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00200.png new file mode 100644 index 0000000..e3945ee Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_htlc/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00021.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_htlc/00021.png rename to tests/snapshots/apex_p/test_sign_tx_htlc/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_htlc/00022.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_htlc/00022.png rename to tests/snapshots/apex_p/test_sign_tx_htlc/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00023.png b/tests/snapshots/apex_p/test_sign_tx_htlc/00300.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00023.png rename to tests/snapshots/apex_p/test_sign_tx_htlc/00300.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00010.png b/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00010.png rename to tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00011.png b/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00011.png rename to tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00012.png b/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00102.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00012.png rename to tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00102.png diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00013.png b/tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00200.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_transfer/00013.png rename to tests/snapshots/apex_p/test_sign_tx_issue_fungible_token/00200.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00010.png b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00010.png deleted file mode 100644 index 6a272b9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00100.png b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00100.png new file mode 100644 index 0000000..4172c1c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00011.png b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_nft/00011.png rename to tests/snapshots/apex_p/test_sign_tx_issue_nft/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00012.png b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00102.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_issue_nft/00012.png rename to tests/snapshots/apex_p/test_sign_tx_issue_nft/00102.png diff --git a/tests/snapshots/apex_p/test_sign_tx_issue_nft/00200.png b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00200.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_issue_nft/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00010.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00010.png deleted file mode 100644 index 49bf43a..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00011.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00011.png deleted file mode 100644 index 49bf43a..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00020.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00020.png deleted file mode 100644 index 7f2f290..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00022.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00022.png deleted file mode 100644 index 1e1fd15..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00022.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00100.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00100.png new file mode 100644 index 0000000..020d4bb Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00101.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00101.png new file mode 100644 index 0000000..020d4bb Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00200.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00200.png new file mode 100644 index 0000000..bd21edc Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00021.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00021.png rename to tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00202.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00202.png new file mode 100644 index 0000000..59494e0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00202.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00300.png b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00300.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_lock_then_transfer/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00010.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00010.png deleted file mode 100644 index 52764e9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00011.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00011.png deleted file mode 100644 index 52764e9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00011.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00020.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00020.png deleted file mode 100644 index 575995c..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00023.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00100.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00100.png new file mode 100644 index 0000000..64925c0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00101.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00101.png new file mode 100644 index 0000000..64925c0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00200.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00200.png new file mode 100644 index 0000000..3d58ef7 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00021.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_mint_tokens/00021.png rename to tests/snapshots/apex_p/test_sign_tx_mint_tokens/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00022.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_mint_tokens/00022.png rename to tests/snapshots/apex_p/test_sign_tx_mint_tokens/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00300.png b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00300.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_mint_tokens/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00010.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00010.png deleted file mode 100644 index 1b74062..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00011.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00011.png deleted file mode 100644 index 1b74062..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00011.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00020.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00020.png deleted file mode 100644 index c7c92d0..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00021.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00021.png deleted file mode 100644 index c7c92d0..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00021.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00030.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00030.png deleted file mode 100644 index 575995c..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00030.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00033.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00033.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00033.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00100.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00100.png new file mode 100644 index 0000000..cabc5a0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00101.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00101.png new file mode 100644 index 0000000..cabc5a0 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00200.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00200.png new file mode 100644 index 0000000..d6ba17f Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00201.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00201.png new file mode 100644 index 0000000..d6ba17f Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00201.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00300.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00300.png new file mode 100644 index 0000000..1b27f40 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00031.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00301.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_order_conclude/00031.png rename to tests/snapshots/apex_p/test_sign_tx_order_conclude/00301.png diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00032.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00302.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_order_conclude/00032.png rename to tests/snapshots/apex_p/test_sign_tx_order_conclude/00302.png diff --git a/tests/snapshots/apex_p/test_sign_tx_order_conclude/00400.png b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00400.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_conclude/00400.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00010.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00010.png deleted file mode 100644 index 1d3567b..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00011.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00011.png deleted file mode 100644 index 1d3567b..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00011.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00020.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00020.png deleted file mode 100644 index c2afd83..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00021.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00021.png deleted file mode 100644 index c2afd83..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00021.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00030.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00030.png deleted file mode 100644 index 575995c..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00030.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00033.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00033.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_order_fill/00033.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00100.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00100.png new file mode 100644 index 0000000..532cadb Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00101.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00101.png new file mode 100644 index 0000000..532cadb Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00200.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00200.png new file mode 100644 index 0000000..e3945ee Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00201.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00201.png new file mode 100644 index 0000000..e3945ee Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00201.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00300.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00300.png new file mode 100644 index 0000000..5ced57b Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00031.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00301.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_order_fill/00031.png rename to tests/snapshots/apex_p/test_sign_tx_order_fill/00301.png diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00032.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00302.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_order_fill/00032.png rename to tests/snapshots/apex_p/test_sign_tx_order_fill/00302.png diff --git a/tests/snapshots/apex_p/test_sign_tx_order_fill/00400.png b/tests/snapshots/apex_p/test_sign_tx_order_fill/00400.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_order_fill/00400.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00010.png b/tests/snapshots/apex_p/test_sign_tx_transfer/00010.png deleted file mode 100644 index 25d533d..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00100.png b/tests/snapshots/apex_p/test_sign_tx_transfer/00100.png new file mode 100644 index 0000000..a7f38f9 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_transfer/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00011.png b/tests/snapshots/apex_p/test_sign_tx_transfer/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_transfer/00011.png rename to tests/snapshots/apex_p/test_sign_tx_transfer/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00012.png b/tests/snapshots/apex_p/test_sign_tx_transfer/00102.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_transfer/00012.png rename to tests/snapshots/apex_p/test_sign_tx_transfer/00102.png diff --git a/tests/snapshots/apex_p/test_sign_tx_transfer/00200.png b/tests/snapshots/apex_p/test_sign_tx_transfer/00200.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_transfer/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00020.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00020.png deleted file mode 100644 index bad1ebd..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00023.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00010.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00010.png rename to tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00011.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00011.png rename to tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00200.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00200.png new file mode 100644 index 0000000..d019bb5 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00021.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00201.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00021.png rename to tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00201.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00022.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00022.png rename to tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00300.png b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00300.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_unfreeze_tokens/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00020.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00020.png deleted file mode 100644 index bad1ebd..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00021.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00021.png deleted file mode 100644 index 896f1de..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00023.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00023.png deleted file mode 100644 index e36e7a9..0000000 Binary files a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00010.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00100.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00010.png rename to tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00100.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00011.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00101.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00011.png rename to tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00101.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00200.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00200.png new file mode 100644 index 0000000..d019bb5 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00201.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00201.png new file mode 100644 index 0000000..c74205e Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00201.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00022.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00202.png similarity index 100% rename from tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00022.png rename to tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00202.png diff --git a/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00300.png b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00300.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_unmint_tokens/00300.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00000.png b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00000.png new file mode 100644 index 0000000..f89ff1c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00100.png b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00100.png new file mode 100644 index 0000000..886bbaf Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00101.png b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00101.png new file mode 100644 index 0000000..cd92a0f Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00102.png b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00102.png new file mode 100644 index 0000000..4b44940 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00102.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00200.png b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00200.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_input_and_commitment/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_output/00000.png b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00000.png new file mode 100644 index 0000000..f89ff1c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_output/00100.png b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00100.png new file mode 100644 index 0000000..4172c1c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_output/00101.png b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00101.png new file mode 100644 index 0000000..3eda950 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_output/00102.png b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00102.png new file mode 100644 index 0000000..6fa38da Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00102.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_with_large_output/00200.png b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00200.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_with_large_output/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_without_outputs/00000.png b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00000.png new file mode 100644 index 0000000..f89ff1c Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00000.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_without_outputs/00100.png b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00100.png new file mode 100644 index 0000000..cd93b66 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00100.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_without_outputs/00101.png b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00101.png new file mode 100644 index 0000000..cd93b66 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00101.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_without_outputs/00200.png b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00200.png new file mode 100644 index 0000000..9b7a3e8 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00200.png differ diff --git a/tests/snapshots/apex_p/test_sign_tx_without_outputs/00300.png b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00300.png new file mode 100644 index 0000000..4aba0a2 Binary files /dev/null and b/tests/snapshots/apex_p/test_sign_tx_without_outputs/00300.png differ diff --git a/tests/snapshots/flex/test_app_mainmenu/00001.png b/tests/snapshots/flex/test_app_mainmenu/00001.png index b3f1c85..a628159 100644 Binary files a/tests/snapshots/flex/test_app_mainmenu/00001.png and b/tests/snapshots/flex/test_app_mainmenu/00001.png differ diff --git a/tests/snapshots/flex/test_app_mainmenu/00002.png b/tests/snapshots/flex/test_app_mainmenu/00002.png deleted file mode 100644 index ad64488..0000000 Binary files a/tests/snapshots/flex/test_app_mainmenu/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_app_mainmenu/00003.png b/tests/snapshots/flex/test_app_mainmenu/00003.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_app_mainmenu/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_get_public_key_confirm_refused/00003.png b/tests/snapshots/flex/test_get_public_key_confirm_refused/00003.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_get_public_key_confirm_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_large_message/00000.png b/tests/snapshots/flex/test_sign_large_message/00000.png new file mode 100644 index 0000000..44e3d67 Binary files /dev/null and b/tests/snapshots/flex/test_sign_large_message/00000.png differ diff --git a/tests/snapshots/flex/test_sign_large_message/00001.png b/tests/snapshots/flex/test_sign_large_message/00001.png new file mode 100644 index 0000000..571fe59 Binary files /dev/null and b/tests/snapshots/flex/test_sign_large_message/00001.png differ diff --git a/tests/snapshots/flex/test_sign_large_message/00002.png b/tests/snapshots/flex/test_sign_large_message/00002.png new file mode 100644 index 0000000..64ddce2 Binary files /dev/null and b/tests/snapshots/flex/test_sign_large_message/00002.png differ diff --git a/tests/snapshots/flex/test_sign_large_message/00003.png b/tests/snapshots/flex/test_sign_large_message/00003.png new file mode 100644 index 0000000..2675d2d Binary files /dev/null and b/tests/snapshots/flex/test_sign_large_message/00003.png differ diff --git a/tests/snapshots/flex/test_sign_large_message/00004.png b/tests/snapshots/flex/test_sign_large_message/00004.png new file mode 100644 index 0000000..f8e68c8 Binary files /dev/null and b/tests/snapshots/flex/test_sign_large_message/00004.png differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00004.png b/tests/snapshots/flex/test_sign_large_message/00005.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_lock_then_transfer/00004.png rename to tests/snapshots/flex/test_sign_large_message/00005.png diff --git a/tests/snapshots/flex/test_sign_message/00000.png b/tests/snapshots/flex/test_sign_message/00000.png index ab24a07..a2a9b36 100644 Binary files a/tests/snapshots/flex/test_sign_message/00000.png and b/tests/snapshots/flex/test_sign_message/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_pkh/00000.png b/tests/snapshots/flex/test_sign_message_pkh/00000.png index ab24a07..a2a9b36 100644 Binary files a/tests/snapshots/flex/test_sign_message_pkh/00000.png and b/tests/snapshots/flex/test_sign_message_pkh/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_refused/00000.png b/tests/snapshots/flex/test_sign_message_refused/00000.png index ab24a07..a2a9b36 100644 Binary files a/tests/snapshots/flex/test_sign_message_refused/00000.png and b/tests/snapshots/flex/test_sign_message_refused/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_refused/00005.png b/tests/snapshots/flex/test_sign_message_refused/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_message_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00001.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00001.png deleted file mode 100644 index a35c8fe..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00002.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00002.png deleted file mode 100644 index f8cf440..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00003.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00003.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00004.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00004.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00020.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00020.png deleted file mode 100644 index 01b72a7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00023.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_authority/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00010.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_authority/00010.png rename to tests/snapshots/flex/test_sign_tx_change_token_authority/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00011.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_authority/00011.png rename to tests/snapshots/flex/test_sign_tx_change_token_authority/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00200.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00200.png new file mode 100644 index 0000000..ada16a3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_change_token_authority/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00021.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_authority/00021.png rename to tests/snapshots/flex/test_sign_tx_change_token_authority/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_authority/00022.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_authority/00022.png rename to tests/snapshots/flex/test_sign_tx_change_token_authority/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00004.png b/tests/snapshots/flex/test_sign_tx_change_token_authority/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_delegation/00004.png rename to tests/snapshots/flex/test_sign_tx_change_token_authority/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00001.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00001.png deleted file mode 100644 index a35c8fe..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00002.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00002.png deleted file mode 100644 index 3d2dbe5..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00003.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00003.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00004.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00004.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00020.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00020.png deleted file mode 100644 index 01b72a7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00023.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00010.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00010.png rename to tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00011.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00011.png rename to tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00200.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00200.png new file mode 100644 index 0000000..ada16a3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00021.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00021.png rename to tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00022.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00022.png rename to tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00013.png b/tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_delegation/00013.png rename to tests/snapshots/flex/test_sign_tx_change_token_metadata_uri/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00001.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00001.png deleted file mode 100644 index 22a1f7f..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_delegation/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00002.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00002.png deleted file mode 100644 index 9a4e534..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_delegation/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00003.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00003.png deleted file mode 100644 index 2fa6cf6..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_delegation/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00005.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_delegation/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00010.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_delegation/00010.png rename to tests/snapshots/flex/test_sign_tx_create_delegation/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00011.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_delegation/00011.png rename to tests/snapshots/flex/test_sign_tx_create_delegation/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_create_delegation/00012.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_delegation/00012.png rename to tests/snapshots/flex/test_sign_tx_create_delegation/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00004.png b/tests/snapshots/flex/test_sign_tx_create_delegation/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_stake_pool/00004.png rename to tests/snapshots/flex/test_sign_tx_create_delegation/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00001.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00001.png deleted file mode 100644 index 4477f6e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00002.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00002.png deleted file mode 100644 index 780f8bd..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00003.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00003.png deleted file mode 100644 index da03051..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00005.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00010.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_stake_pool/00010.png rename to tests/snapshots/flex/test_sign_tx_create_stake_pool/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00011.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_stake_pool/00011.png rename to tests/snapshots/flex/test_sign_tx_create_stake_pool/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00012.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_stake_pool/00012.png rename to tests/snapshots/flex/test_sign_tx_create_stake_pool/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_create_stake_pool/00013.png b/tests/snapshots/flex/test_sign_tx_create_stake_pool/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_create_stake_pool/00013.png rename to tests/snapshots/flex/test_sign_tx_create_stake_pool/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00000.png b/tests/snapshots/flex/test_sign_tx_delegate_staking/00000.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_delegation_staking/00000.png rename to tests/snapshots/flex/test_sign_tx_delegate_staking/00000.png diff --git a/tests/snapshots/flex/test_sign_tx_delegate_staking/00100.png b/tests/snapshots/flex/test_sign_tx_delegate_staking/00100.png new file mode 100644 index 0000000..d3234b0 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_delegate_staking/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00011.png b/tests/snapshots/flex/test_sign_tx_delegate_staking/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_delegation_staking/00011.png rename to tests/snapshots/flex/test_sign_tx_delegate_staking/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_delegate_staking/00102.png b/tests/snapshots/flex/test_sign_tx_delegate_staking/00102.png new file mode 100644 index 0000000..824c2d0 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_delegate_staking/00102.png differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00003.png b/tests/snapshots/flex/test_sign_tx_delegate_staking/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_delegation_staking/00003.png rename to tests/snapshots/flex/test_sign_tx_delegate_staking/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00001.png b/tests/snapshots/flex/test_sign_tx_delegation_staking/00001.png deleted file mode 100644 index 77e8ab2..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_delegation_staking/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00002.png b/tests/snapshots/flex/test_sign_tx_delegation_staking/00002.png deleted file mode 100644 index 93e8caf..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_delegation_staking/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00004.png b/tests/snapshots/flex/test_sign_tx_delegation_staking/00004.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_delegation_staking/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00010.png b/tests/snapshots/flex/test_sign_tx_delegation_staking/00010.png deleted file mode 100644 index d559d03..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_delegation_staking/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00012.png b/tests/snapshots/flex/test_sign_tx_delegation_staking/00012.png deleted file mode 100644 index 0214b02..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_delegation_staking/00012.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00001.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00001.png deleted file mode 100644 index a35c8fe..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00002.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00002.png deleted file mode 100644 index 4a5b80c..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00003.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00003.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00004.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00004.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00020.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00020.png deleted file mode 100644 index 01b72a7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00023.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00010.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_freeze_tokens/00010.png rename to tests/snapshots/flex/test_sign_tx_freeze_tokens/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00011.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_freeze_tokens/00011.png rename to tests/snapshots/flex/test_sign_tx_freeze_tokens/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00200.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00200.png new file mode 100644 index 0000000..ada16a3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00021.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_freeze_tokens/00021.png rename to tests/snapshots/flex/test_sign_tx_freeze_tokens/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_freeze_tokens/00022.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_freeze_tokens/00022.png rename to tests/snapshots/flex/test_sign_tx_freeze_tokens/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_delegation_staking/00013.png b/tests/snapshots/flex/test_sign_tx_freeze_tokens/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_delegation_staking/00013.png rename to tests/snapshots/flex/test_sign_tx_freeze_tokens/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00001.png b/tests/snapshots/flex/test_sign_tx_htlc/00001.png deleted file mode 100644 index f2dcdf5..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_htlc/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00002.png b/tests/snapshots/flex/test_sign_tx_htlc/00002.png deleted file mode 100644 index fa66a8a..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_htlc/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00003.png b/tests/snapshots/flex/test_sign_tx_htlc/00003.png deleted file mode 100644 index da95e9c..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_htlc/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00005.png b/tests/snapshots/flex/test_sign_tx_htlc/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_htlc/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00020.png b/tests/snapshots/flex/test_sign_tx_htlc/00020.png deleted file mode 100644 index ddbc1a4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_htlc/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00010.png b/tests/snapshots/flex/test_sign_tx_htlc/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00010.png rename to tests/snapshots/flex/test_sign_tx_htlc/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00011.png b/tests/snapshots/flex/test_sign_tx_htlc/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00011.png rename to tests/snapshots/flex/test_sign_tx_htlc/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00200.png b/tests/snapshots/flex/test_sign_tx_htlc/00200.png new file mode 100644 index 0000000..72c7dec Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_htlc/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00021.png b/tests/snapshots/flex/test_sign_tx_htlc/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00021.png rename to tests/snapshots/flex/test_sign_tx_htlc/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00022.png b/tests/snapshots/flex/test_sign_tx_htlc/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00022.png rename to tests/snapshots/flex/test_sign_tx_htlc/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00004.png b/tests/snapshots/flex/test_sign_tx_htlc/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00004.png rename to tests/snapshots/flex/test_sign_tx_htlc/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00001.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00001.png deleted file mode 100644 index 06c369e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00002.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00002.png deleted file mode 100644 index 9a4e534..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00003.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00003.png deleted file mode 100644 index 3babddd..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00005.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00010.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_fungible_token/00010.png rename to tests/snapshots/flex/test_sign_tx_issue_fungible_token/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00011.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_fungible_token/00011.png rename to tests/snapshots/flex/test_sign_tx_issue_fungible_token/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00012.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_fungible_token/00012.png rename to tests/snapshots/flex/test_sign_tx_issue_fungible_token/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_htlc/00023.png b/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_htlc/00023.png rename to tests/snapshots/flex/test_sign_tx_issue_fungible_token/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00001.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00001.png deleted file mode 100644 index f7f99ec..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_nft/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00002.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00002.png deleted file mode 100644 index 36cc105..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_nft/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00003.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00003.png deleted file mode 100644 index 2d3241f..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_nft/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00005.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_nft/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00010.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00010.png deleted file mode 100644 index 78a5ee8..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_issue_nft/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00100.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00100.png new file mode 100644 index 0000000..49a16a2 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_issue_nft/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00011.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_nft/00011.png rename to tests/snapshots/flex/test_sign_tx_issue_nft/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00012.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_nft/00012.png rename to tests/snapshots/flex/test_sign_tx_issue_nft/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00004.png b/tests/snapshots/flex/test_sign_tx_issue_nft/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_fungible_token/00004.png rename to tests/snapshots/flex/test_sign_tx_issue_nft/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00002.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00002.png deleted file mode 100644 index d0597b4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00005.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00010.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00010.png deleted file mode 100644 index 53b5831..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00011.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00011.png deleted file mode 100644 index 53b5831..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00012.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00012.png deleted file mode 100644 index bb4b77a..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00012.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00020.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00020.png deleted file mode 100644 index 484200d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00022.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00022.png deleted file mode 100644 index d0597b4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00022.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00100.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00100.png new file mode 100644 index 0000000..bd5df4f Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00101.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00101.png new file mode 100644 index 0000000..bd5df4f Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00200.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00200.png new file mode 100644 index 0000000..ea07f63 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00001.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_lock_then_transfer/00001.png rename to tests/snapshots/flex/test_sign_tx_lock_then_transfer/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00202.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00202.png new file mode 100644 index 0000000..c8eb2cf Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00202.png differ diff --git a/tests/snapshots/flex/test_sign_tx_issue_fungible_token/00013.png b/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_fungible_token/00013.png rename to tests/snapshots/flex/test_sign_tx_lock_then_transfer/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00000.png b/tests/snapshots/flex/test_sign_tx_long_tx/00000.png deleted file mode 100644 index 0649145..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00001.png b/tests/snapshots/flex/test_sign_tx_long_tx/00001.png deleted file mode 100644 index fa1a974..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00002.png b/tests/snapshots/flex/test_sign_tx_long_tx/00002.png deleted file mode 100644 index ff0fd44..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00003.png b/tests/snapshots/flex/test_sign_tx_long_tx/00003.png deleted file mode 100644 index fd33e09..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00004.png b/tests/snapshots/flex/test_sign_tx_long_tx/00004.png deleted file mode 100644 index be51a9d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_long_tx/00005.png b/tests/snapshots/flex/test_sign_tx_long_tx/00005.png deleted file mode 100644 index 8a9212d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_long_tx/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00001.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00001.png deleted file mode 100644 index a7e344d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00002.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00002.png deleted file mode 100644 index 82d6a13..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00003.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00003.png deleted file mode 100644 index 55d938e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00004.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00004.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00005.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00005.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00010.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00010.png deleted file mode 100644 index eb4eae4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00011.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00011.png deleted file mode 100644 index eb4eae4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00011.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00020.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00020.png deleted file mode 100644 index bfbc477..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00023.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_mint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00100.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00100.png new file mode 100644 index 0000000..16bf59a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_mint_tokens/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00101.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00101.png new file mode 100644 index 0000000..16bf59a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_mint_tokens/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00200.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00200.png new file mode 100644 index 0000000..7f084db Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_mint_tokens/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00021.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_mint_tokens/00021.png rename to tests/snapshots/flex/test_sign_tx_mint_tokens/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_mint_tokens/00022.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_mint_tokens/00022.png rename to tests/snapshots/flex/test_sign_tx_mint_tokens/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00004.png b/tests/snapshots/flex/test_sign_tx_mint_tokens/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_nft/00004.png rename to tests/snapshots/flex/test_sign_tx_mint_tokens/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00001.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00001.png deleted file mode 100644 index b27ad50..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00002.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00002.png deleted file mode 100644 index f198ed6..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00003.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00003.png deleted file mode 100644 index 5c9b386..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00004.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00004.png deleted file mode 100644 index 3ab6bae..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00005.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00005.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00006.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00006.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00006.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00010.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00010.png deleted file mode 100644 index 08d878b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00011.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00011.png deleted file mode 100644 index 08d878b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00011.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00020.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00020.png deleted file mode 100644 index da876bd..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00021.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00021.png deleted file mode 100644 index da876bd..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00021.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00030.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00030.png deleted file mode 100644 index b43304b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00030.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00033.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00033.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_conclude/00033.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00100.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00100.png new file mode 100644 index 0000000..29b3fad Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_conclude/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00101.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00101.png new file mode 100644 index 0000000..29b3fad Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_conclude/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00200.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00200.png new file mode 100644 index 0000000..eddbba3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_conclude/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00201.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00201.png new file mode 100644 index 0000000..eddbba3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_conclude/00201.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00300.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00300.png new file mode 100644 index 0000000..a05b1c4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_conclude/00300.png differ diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00021.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00301.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_lock_then_transfer/00021.png rename to tests/snapshots/flex/test_sign_tx_order_conclude/00301.png diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00032.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00302.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_order_conclude/00032.png rename to tests/snapshots/flex/test_sign_tx_order_conclude/00302.png diff --git a/tests/snapshots/flex/test_sign_tx_issue_nft/00013.png b/tests/snapshots/flex/test_sign_tx_order_conclude/00400.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_issue_nft/00013.png rename to tests/snapshots/flex/test_sign_tx_order_conclude/00400.png diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00001.png b/tests/snapshots/flex/test_sign_tx_order_fill/00001.png deleted file mode 100644 index 7657c0b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00002.png b/tests/snapshots/flex/test_sign_tx_order_fill/00002.png deleted file mode 100644 index d67d882..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00003.png b/tests/snapshots/flex/test_sign_tx_order_fill/00003.png deleted file mode 100644 index 5c9b386..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00004.png b/tests/snapshots/flex/test_sign_tx_order_fill/00004.png deleted file mode 100644 index 4e3f52b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00005.png b/tests/snapshots/flex/test_sign_tx_order_fill/00005.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00006.png b/tests/snapshots/flex/test_sign_tx_order_fill/00006.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00006.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00010.png b/tests/snapshots/flex/test_sign_tx_order_fill/00010.png deleted file mode 100644 index b613574..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00011.png b/tests/snapshots/flex/test_sign_tx_order_fill/00011.png deleted file mode 100644 index b613574..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00011.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00020.png b/tests/snapshots/flex/test_sign_tx_order_fill/00020.png deleted file mode 100644 index ddbc1a4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00021.png b/tests/snapshots/flex/test_sign_tx_order_fill/00021.png deleted file mode 100644 index ddbc1a4..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00021.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00030.png b/tests/snapshots/flex/test_sign_tx_order_fill/00030.png deleted file mode 100644 index 08604b0..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00030.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00033.png b/tests/snapshots/flex/test_sign_tx_order_fill/00033.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_order_fill/00033.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00100.png b/tests/snapshots/flex/test_sign_tx_order_fill/00100.png new file mode 100644 index 0000000..3b5a1b7 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_fill/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00101.png b/tests/snapshots/flex/test_sign_tx_order_fill/00101.png new file mode 100644 index 0000000..3b5a1b7 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_fill/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00200.png b/tests/snapshots/flex/test_sign_tx_order_fill/00200.png new file mode 100644 index 0000000..72c7dec Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_fill/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00201.png b/tests/snapshots/flex/test_sign_tx_order_fill/00201.png new file mode 100644 index 0000000..72c7dec Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_fill/00201.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00300.png b/tests/snapshots/flex/test_sign_tx_order_fill/00300.png new file mode 100644 index 0000000..e312050 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_order_fill/00300.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_conclude/00031.png b/tests/snapshots/flex/test_sign_tx_order_fill/00301.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_order_conclude/00031.png rename to tests/snapshots/flex/test_sign_tx_order_fill/00301.png diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00032.png b/tests/snapshots/flex/test_sign_tx_order_fill/00302.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_order_fill/00032.png rename to tests/snapshots/flex/test_sign_tx_order_fill/00302.png diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00003.png b/tests/snapshots/flex/test_sign_tx_order_fill/00400.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_lock_then_transfer/00003.png rename to tests/snapshots/flex/test_sign_tx_order_fill/00400.png diff --git a/tests/snapshots/flex/test_sign_tx_refused/00000.png b/tests/snapshots/flex/test_sign_tx_refused/00000.png deleted file mode 100644 index c2a4a2f..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00000.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_refused/00001.png b/tests/snapshots/flex/test_sign_tx_refused/00001.png deleted file mode 100644 index 5d919f7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_refused/00002.png b/tests/snapshots/flex/test_sign_tx_refused/00002.png deleted file mode 100644 index 9a270f5..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_refused/00003.png b/tests/snapshots/flex/test_sign_tx_refused/00003.png deleted file mode 100644 index 6a11e11..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_refused/00004.png b/tests/snapshots/flex/test_sign_tx_refused/00004.png deleted file mode 100644 index 6bbdf2f..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_refused/00005.png b/tests/snapshots/flex/test_sign_tx_refused/00005.png deleted file mode 100644 index 8a9212d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00000.png b/tests/snapshots/flex/test_sign_tx_short_tx/00000.png deleted file mode 100644 index d60a071..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00001.png b/tests/snapshots/flex/test_sign_tx_short_tx/00001.png deleted file mode 100644 index fe24a7b..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00002.png b/tests/snapshots/flex/test_sign_tx_short_tx/00002.png deleted file mode 100644 index 7752e76..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00003.png b/tests/snapshots/flex/test_sign_tx_short_tx/00003.png deleted file mode 100644 index 6d18dff..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00004.png b/tests/snapshots/flex/test_sign_tx_short_tx/00004.png deleted file mode 100644 index be51a9d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx/00005.png b/tests/snapshots/flex/test_sign_tx_short_tx/00005.png deleted file mode 100644 index ca1717c..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00000.png b/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00000.png deleted file mode 100644 index c2a4a2f..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00000.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00001.png b/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00001.png deleted file mode 100644 index 2d0c474..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00002.png b/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00002.png deleted file mode 100644 index 9a270f5..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00003.png b/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00003.png deleted file mode 100644 index be51a9d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00004.png b/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00004.png deleted file mode 100644 index 8a9212d..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_short_tx_no_memo/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00004.png b/tests/snapshots/flex/test_sign_tx_transfer/00004.png deleted file mode 100644 index f2fa972..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_transfer/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00005.png b/tests/snapshots/flex/test_sign_tx_transfer/00005.png deleted file mode 100644 index c0e88bb..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_transfer/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00010.png b/tests/snapshots/flex/test_sign_tx_transfer/00010.png deleted file mode 100644 index 016f0ec..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00011.png b/tests/snapshots/flex/test_sign_tx_transfer/00011.png deleted file mode 100644 index 67a9b5a..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00100.png b/tests/snapshots/flex/test_sign_tx_transfer/00100.png new file mode 100644 index 0000000..a6e4d55 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_transfer/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00001.png b/tests/snapshots/flex/test_sign_tx_transfer/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_transfer/00001.png rename to tests/snapshots/flex/test_sign_tx_transfer/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00002.png b/tests/snapshots/flex/test_sign_tx_transfer/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_transfer/00002.png rename to tests/snapshots/flex/test_sign_tx_transfer/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_lock_then_transfer/00023.png b/tests/snapshots/flex/test_sign_tx_transfer/00200.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_lock_then_transfer/00023.png rename to tests/snapshots/flex/test_sign_tx_transfer/00200.png diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00001.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00001.png deleted file mode 100644 index a35c8fe..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00002.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00002.png deleted file mode 100644 index 06b6496..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00003.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00003.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00004.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00004.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00020.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00020.png deleted file mode 100644 index 01b72a7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00021.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00021.png deleted file mode 100644 index 8a8445e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00023.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00010.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00010.png rename to tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00011.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00011.png rename to tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00200.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00200.png new file mode 100644 index 0000000..ada16a3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_order_fill/00031.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00201.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_order_fill/00031.png rename to tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00201.png diff --git a/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00022.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00022.png rename to tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00003.png b/tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_transfer/00003.png rename to tests/snapshots/flex/test_sign_tx_unfreeze_tokens/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00001.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00001.png deleted file mode 100644 index d8a9bad..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00002.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00002.png deleted file mode 100644 index 7a34a97..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00003.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00003.png deleted file mode 100644 index a3c1ec1..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00004.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00004.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00005.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00005.png deleted file mode 100644 index 553394e..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00020.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00020.png deleted file mode 100644 index 01b72a7..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00021.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00021.png deleted file mode 100644 index 2d9e0a0..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00023.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00023.png deleted file mode 100644 index 9f79b05..0000000 Binary files a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00010.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00100.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unmint_tokens/00010.png rename to tests/snapshots/flex/test_sign_tx_unmint_tokens/00100.png diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00011.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00101.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unmint_tokens/00011.png rename to tests/snapshots/flex/test_sign_tx_unmint_tokens/00101.png diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00200.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00200.png new file mode 100644 index 0000000..ada16a3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00201.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00201.png new file mode 100644 index 0000000..bf6752a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00201.png differ diff --git a/tests/snapshots/flex/test_sign_tx_unmint_tokens/00022.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00202.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_unmint_tokens/00022.png rename to tests/snapshots/flex/test_sign_tx_unmint_tokens/00202.png diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00013.png b/tests/snapshots/flex/test_sign_tx_unmint_tokens/00300.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_transfer/00013.png rename to tests/snapshots/flex/test_sign_tx_unmint_tokens/00300.png diff --git a/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00000.png b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00000.png new file mode 100644 index 0000000..5d42a9a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00000.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00100.png b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00100.png new file mode 100644 index 0000000..b8e8fc2 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00101.png b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00101.png new file mode 100644 index 0000000..5880f40 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_transfer/00012.png b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00102.png similarity index 100% rename from tests/snapshots/flex/test_sign_tx_transfer/00012.png rename to tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00102.png diff --git a/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00200.png b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00200.png new file mode 100644 index 0000000..435aa78 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_input_and_commitment/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_output/00000.png b/tests/snapshots/flex/test_sign_tx_with_large_output/00000.png new file mode 100644 index 0000000..5d42a9a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_output/00000.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_output/00100.png b/tests/snapshots/flex/test_sign_tx_with_large_output/00100.png new file mode 100644 index 0000000..49a16a2 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_output/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_output/00101.png b/tests/snapshots/flex/test_sign_tx_with_large_output/00101.png new file mode 100644 index 0000000..c77916a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_output/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_output/00102.png b/tests/snapshots/flex/test_sign_tx_with_large_output/00102.png new file mode 100644 index 0000000..b1edb3e Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_output/00102.png differ diff --git a/tests/snapshots/flex/test_sign_tx_with_large_output/00200.png b/tests/snapshots/flex/test_sign_tx_with_large_output/00200.png new file mode 100644 index 0000000..435aa78 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_with_large_output/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_without_outputs/00000.png b/tests/snapshots/flex/test_sign_tx_without_outputs/00000.png new file mode 100644 index 0000000..5d42a9a Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_without_outputs/00000.png differ diff --git a/tests/snapshots/flex/test_sign_tx_without_outputs/00100.png b/tests/snapshots/flex/test_sign_tx_without_outputs/00100.png new file mode 100644 index 0000000..f156168 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_without_outputs/00100.png differ diff --git a/tests/snapshots/flex/test_sign_tx_without_outputs/00101.png b/tests/snapshots/flex/test_sign_tx_without_outputs/00101.png new file mode 100644 index 0000000..f156168 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_without_outputs/00101.png differ diff --git a/tests/snapshots/flex/test_sign_tx_without_outputs/00200.png b/tests/snapshots/flex/test_sign_tx_without_outputs/00200.png new file mode 100644 index 0000000..aa0f0aa Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_without_outputs/00200.png differ diff --git a/tests/snapshots/flex/test_sign_tx_without_outputs/00300.png b/tests/snapshots/flex/test_sign_tx_without_outputs/00300.png new file mode 100644 index 0000000..435aa78 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_without_outputs/00300.png differ diff --git a/tests/snapshots/nanosp/test_app_mainmenu/00003.png b/tests/snapshots/nanosp/test_app_mainmenu/00003.png deleted file mode 100644 index f265d69..0000000 Binary files a/tests/snapshots/nanosp/test_app_mainmenu/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00005.png b/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00005.png deleted file mode 100644 index 32e7443..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00006.png b/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_accepted/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00006.png b/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00006.png deleted file mode 100644 index fbfed86..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00007.png b/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00007.png deleted file mode 100644 index bdbc0ff..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00008.png b/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00008.png deleted file mode 100644 index 77bcafd..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00009.png b/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00009.png deleted file mode 100644 index f265d69..0000000 Binary files a/tests/snapshots/nanosp/test_get_public_key_confirm_refused/00009.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00000.png b/tests/snapshots/nanosp/test_sign_large_message/00000.png new file mode 100644 index 0000000..2e4d511 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00001.png b/tests/snapshots/nanosp/test_sign_large_message/00001.png new file mode 100644 index 0000000..602c22a Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00002.png b/tests/snapshots/nanosp/test_sign_large_message/00002.png new file mode 100644 index 0000000..305308f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00003.png b/tests/snapshots/nanosp/test_sign_large_message/00003.png new file mode 100644 index 0000000..7802e92 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00004.png b/tests/snapshots/nanosp/test_sign_large_message/00004.png new file mode 100644 index 0000000..40bdb70 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00005.png b/tests/snapshots/nanosp/test_sign_large_message/00005.png new file mode 100644 index 0000000..850225e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00005.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00006.png b/tests/snapshots/nanosp/test_sign_large_message/00006.png new file mode 100644 index 0000000..cec141b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00006.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00007.png b/tests/snapshots/nanosp/test_sign_large_message/00007.png new file mode 100644 index 0000000..36eb31d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00007.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00008.png b/tests/snapshots/nanosp/test_sign_large_message/00008.png new file mode 100644 index 0000000..df753a1 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00008.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00009.png b/tests/snapshots/nanosp/test_sign_large_message/00009.png new file mode 100644 index 0000000..d5b841e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00009.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00010.png b/tests/snapshots/nanosp/test_sign_large_message/00010.png new file mode 100644 index 0000000..f5e85c3 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00010.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00011.png b/tests/snapshots/nanosp/test_sign_large_message/00011.png new file mode 100644 index 0000000..d22ac2d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00011.png differ diff --git a/tests/snapshots/nanosp/test_sign_large_message/00012.png b/tests/snapshots/nanosp/test_sign_large_message/00012.png new file mode 100644 index 0000000..55bb5c8 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_large_message/00012.png differ diff --git a/tests/snapshots/nanosp/test_sign_message/00006.png b/tests/snapshots/nanosp/test_sign_large_message/00013.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_message/00006.png rename to tests/snapshots/nanosp/test_sign_large_message/00013.png diff --git a/tests/snapshots/nanosp/test_sign_message/00001.png b/tests/snapshots/nanosp/test_sign_message/00001.png index 8cae4d6..602c22a 100644 Binary files a/tests/snapshots/nanosp/test_sign_message/00001.png and b/tests/snapshots/nanosp/test_sign_message/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message/00002.png b/tests/snapshots/nanosp/test_sign_message/00002.png index 602c22a..305308f 100644 Binary files a/tests/snapshots/nanosp/test_sign_message/00002.png and b/tests/snapshots/nanosp/test_sign_message/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_message/00003.png b/tests/snapshots/nanosp/test_sign_message/00003.png index 305308f..3617b8d 100644 Binary files a/tests/snapshots/nanosp/test_sign_message/00003.png and b/tests/snapshots/nanosp/test_sign_message/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_message/00004.png b/tests/snapshots/nanosp/test_sign_message/00004.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanosp/test_sign_message/00004.png and b/tests/snapshots/nanosp/test_sign_message/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_message/00005.png b/tests/snapshots/nanosp/test_sign_message/00005.png index 55bb5c8..ab20bae 100644 Binary files a/tests/snapshots/nanosp/test_sign_message/00005.png and b/tests/snapshots/nanosp/test_sign_message/00005.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_pkh/00001.png b/tests/snapshots/nanosp/test_sign_message_pkh/00001.png index 8cae4d6..208f5d8 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_pkh/00001.png and b/tests/snapshots/nanosp/test_sign_message_pkh/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_pkh/00002.png b/tests/snapshots/nanosp/test_sign_message_pkh/00002.png index 208f5d8..3617b8d 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_pkh/00002.png and b/tests/snapshots/nanosp/test_sign_message_pkh/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_pkh/00003.png b/tests/snapshots/nanosp/test_sign_message_pkh/00003.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_pkh/00003.png and b/tests/snapshots/nanosp/test_sign_message_pkh/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_pkh/00004.png b/tests/snapshots/nanosp/test_sign_message_pkh/00004.png index 55bb5c8..ab20bae 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_pkh/00004.png and b/tests/snapshots/nanosp/test_sign_message_pkh/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00001.png b/tests/snapshots/nanosp/test_sign_message_refused/00001.png index 8cae4d6..602c22a 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00001.png and b/tests/snapshots/nanosp/test_sign_message_refused/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00002.png b/tests/snapshots/nanosp/test_sign_message_refused/00002.png index 602c22a..305308f 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00002.png and b/tests/snapshots/nanosp/test_sign_message_refused/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00003.png b/tests/snapshots/nanosp/test_sign_message_refused/00003.png index 305308f..3617b8d 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00003.png and b/tests/snapshots/nanosp/test_sign_message_refused/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00004.png b/tests/snapshots/nanosp/test_sign_message_refused/00004.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00004.png and b/tests/snapshots/nanosp/test_sign_message_refused/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00005.png b/tests/snapshots/nanosp/test_sign_message_refused/00005.png index 55bb5c8..12caa58 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00005.png and b/tests/snapshots/nanosp/test_sign_message_refused/00005.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00006.png b/tests/snapshots/nanosp/test_sign_message_refused/00006.png index 12caa58..d917d19 100644 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00006.png and b/tests/snapshots/nanosp/test_sign_message_refused/00006.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_refused/00007.png b/tests/snapshots/nanosp/test_sign_message_refused/00007.png deleted file mode 100644 index d917d19..0000000 Binary files a/tests/snapshots/nanosp/test_sign_message_refused/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00002.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00004.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00004.png deleted file mode 100644 index 2fca943..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00005.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00006.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00010.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00010.png deleted file mode 100644 index c408134..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00011.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00011.png deleted file mode 100644 index fc6fca6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00012.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00012.png deleted file mode 100644 index e2577f8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00013.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00013.png deleted file mode 100644 index aa75038..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00013.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00022.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00100.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00100.png new file mode 100644 index 0000000..15fea9d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00101.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00101.png new file mode 100644 index 0000000..bc691a7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00102.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00102.png new file mode 100644 index 0000000..28ee9c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00103.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00103.png new file mode 100644 index 0000000..9832913 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00020.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00020.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00001.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00001.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00202.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00023.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00023.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00003.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00003.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00025.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00025.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00007.png b/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00007.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_authority/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00002.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00004.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00004.png deleted file mode 100644 index c7d5676..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00005.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00006.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00010.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00010.png deleted file mode 100644 index de18f19..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00011.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00011.png deleted file mode 100644 index 39359b8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00012.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00012.png deleted file mode 100644 index c335313..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00022.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00100.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00100.png new file mode 100644 index 0000000..196af3c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00101.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00101.png new file mode 100644 index 0000000..08f05af Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00102.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00102.png new file mode 100644 index 0000000..5057eb0 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00020.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00020.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00021.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00021.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00202.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00023.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00023.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_authority/00024.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_authority/00024.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00025.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00025.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00008.png b/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00008.png rename to tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00010.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00010.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00001.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00001.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00002.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00002.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00003.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00003.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00004.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00004.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00104.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00005.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00105.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00005.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00105.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00006.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00106.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00006.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00106.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00005.png b/tests/snapshots/nanosp/test_sign_tx_create_delegation/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00005.png rename to tests/snapshots/nanosp/test_sign_tx_create_delegation/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00001.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00001.png deleted file mode 100644 index 3fbfcda..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00002.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00002.png deleted file mode 100644 index dc3f263..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00003.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00003.png deleted file mode 100644 index dd49ec2..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00004.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00004.png deleted file mode 100644 index 7623766..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00005.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00005.png deleted file mode 100644 index 0562b8b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00006.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00006.png deleted file mode 100644 index 9880fbf..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00007.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00007.png deleted file mode 100644 index 5d19c53..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00008.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00008.png deleted file mode 100644 index 7184c47..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00009.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00009.png deleted file mode 100644 index f278bff..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00009.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00010.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00010.png deleted file mode 100644 index 139058c..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00011.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00011.png deleted file mode 100644 index dc3f263..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00012.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00012.png deleted file mode 100644 index dd49ec2..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00013.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00013.png deleted file mode 100644 index 7623766..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00013.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00014.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00014.png deleted file mode 100644 index 0562b8b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00014.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00015.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00015.png deleted file mode 100644 index 9880fbf..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00015.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00016.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00016.png deleted file mode 100644 index 5d19c53..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00016.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00017.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00017.png deleted file mode 100644 index 7184c47..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00017.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00018.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00018.png deleted file mode 100644 index f278bff..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00018.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00019.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00019.png deleted file mode 100644 index 06704db..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00019.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00100.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00100.png new file mode 100644 index 0000000..ad24691 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00101.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00101.png new file mode 100644 index 0000000..bd7a27e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00102.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00102.png new file mode 100644 index 0000000..cb8a713 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00103.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00103.png new file mode 100644 index 0000000..af79c8c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00104.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00104.png new file mode 100644 index 0000000..38c565f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00104.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00105.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00105.png new file mode 100644 index 0000000..bd5c339 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00105.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00106.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00106.png new file mode 100644 index 0000000..b1cd9fe Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00106.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00107.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00107.png new file mode 100644 index 0000000..e35ffb0 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00107.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00108.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00108.png new file mode 100644 index 0000000..42713e3 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00108.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00109.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00109.png new file mode 100644 index 0000000..5418fd7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00109.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00014.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00110.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00014.png rename to tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00110.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00003.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00111.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00003.png rename to tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00111.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00022.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00112.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00022.png rename to tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00112.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00006.png b/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00006.png rename to tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00000.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00000.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00000.png rename to tests/snapshots/nanosp/test_sign_tx_delegate_staking/00000.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00010.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00010.png rename to tests/snapshots/nanosp/test_sign_tx_delegate_staking/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00101.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00101.png new file mode 100644 index 0000000..722145c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00020.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00020.png rename to tests/snapshots/nanosp/test_sign_tx_delegate_staking/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00003.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00003.png rename to tests/snapshots/nanosp/test_sign_tx_delegate_staking/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00104.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00104.png new file mode 100644 index 0000000..e0ad1f1 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00104.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00008.png b/tests/snapshots/nanosp/test_sign_tx_delegate_staking/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00008.png rename to tests/snapshots/nanosp/test_sign_tx_delegate_staking/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00001.png b/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00001.png deleted file mode 100644 index 3645243..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00002.png b/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00002.png deleted file mode 100644 index 2df9d67..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00004.png b/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00004.png deleted file mode 100644 index bbd76c8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00011.png b/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00011.png deleted file mode 100644 index 52979b5..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00014.png b/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00014.png deleted file mode 100644 index c6836c8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00014.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00002.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00004.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00004.png deleted file mode 100644 index bc9b1a8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00005.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00006.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00022.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00010.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00010.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00011.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00011.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00012.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00012.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00001.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00001.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00202.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00020.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00020.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00024.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00024.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00025.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00025.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00009.png b/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00009.png rename to tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00001.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00001.png deleted file mode 100644 index aab0aed..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_htlc/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00006.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00006.png deleted file mode 100644 index 5fc12d1..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_htlc/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00008.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00008.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_htlc/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00015.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00015.png deleted file mode 100644 index 5fc12d1..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_htlc/00015.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00022.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00022.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_htlc/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00010.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00010.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00002.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00002.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00003.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00003.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00004.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00004.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00005.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00005.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00104.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00105.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00105.png new file mode 100644 index 0000000..9949b8d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_htlc/00105.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00023.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00023.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00021.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_change_token_metadata_uri/00021.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00202.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00202.png new file mode 100644 index 0000000..607670c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_htlc/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00020.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00020.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00021.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_stake_pool/00021.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00025.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00025.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00007.png b/tests/snapshots/nanosp/test_sign_tx_htlc/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00007.png rename to tests/snapshots/nanosp/test_sign_tx_htlc/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00001.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00001.png deleted file mode 100644 index 00051f8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00002.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00002.png deleted file mode 100644 index c09832c..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00003.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00003.png deleted file mode 100644 index 419f5f0..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00004.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00004.png deleted file mode 100644 index 26db145..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00005.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00005.png deleted file mode 100644 index 060d61b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00007.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00007.png deleted file mode 100644 index d3ca23a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00013.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00013.png deleted file mode 100644 index 6d1bc9a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00013.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00014.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00014.png deleted file mode 100644 index 4c43c01..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00014.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00010.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00010.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00011.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00011.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00012.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00012.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00103.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00103.png new file mode 100644 index 0000000..77eedd9 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00104.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00104.png new file mode 100644 index 0000000..f589bbf Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00104.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00023.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00105.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00023.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00105.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00015.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00106.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00015.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00106.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00017.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00107.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00017.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00107.png diff --git a/tests/snapshots/nanosp/test_sign_tx_long_tx/00004.png b/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_long_tx/00004.png rename to tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00001.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00001.png deleted file mode 100644 index 2318573..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00002.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00002.png deleted file mode 100644 index d84fdcd..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00003.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00003.png deleted file mode 100644 index 415b46b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00004.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00004.png deleted file mode 100644 index 7fb1f67..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00005.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00005.png deleted file mode 100644 index e14acb6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00006.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00006.png deleted file mode 100644 index 03f61f6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00007.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00007.png deleted file mode 100644 index f678edc..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00008.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00008.png deleted file mode 100644 index 0a262d5..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00009.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00009.png deleted file mode 100644 index 1a586fb..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00009.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00010.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00010.png deleted file mode 100644 index 84ff3f7..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00011.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00011.png deleted file mode 100644 index 3fdec7f..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00012.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00012.png deleted file mode 100644 index a9bd3e2..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00013.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00013.png deleted file mode 100644 index b9a3aba..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00013.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00014.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00014.png deleted file mode 100644 index b69697c..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00014.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00015.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00015.png deleted file mode 100644 index 651a3f4..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00015.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00016.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00016.png deleted file mode 100644 index 19e1140..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00016.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00017.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00017.png deleted file mode 100644 index 95bb380..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00017.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00018.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00018.png deleted file mode 100644 index 4cf446c..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00018.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00100.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00100.png new file mode 100644 index 0000000..8b7b71f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00101.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00101.png new file mode 100644 index 0000000..9d40b0b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00102.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00102.png new file mode 100644 index 0000000..64c4618 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00103.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00103.png new file mode 100644 index 0000000..2400405 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00104.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00104.png new file mode 100644 index 0000000..2f750b3 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00104.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00105.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00105.png new file mode 100644 index 0000000..e3ef4c1 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00105.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00106.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00106.png new file mode 100644 index 0000000..bc9c4a5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00106.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00107.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00107.png new file mode 100644 index 0000000..77dec68 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00107.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00108.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00108.png new file mode 100644 index 0000000..6d7bef4 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00108.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00109.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00109.png new file mode 100644 index 0000000..8bf8d9b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00109.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00015.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00110.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00015.png rename to tests/snapshots/nanosp/test_sign_tx_issue_nft/00110.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00020.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00111.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_nft/00020.png rename to tests/snapshots/nanosp/test_sign_tx_issue_nft/00111.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00021.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00112.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_nft/00021.png rename to tests/snapshots/nanosp/test_sign_tx_issue_nft/00112.png diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00006.png b/tests/snapshots/nanosp/test_sign_tx_issue_nft/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_short_tx/00006.png rename to tests/snapshots/nanosp/test_sign_tx_issue_nft/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00003.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00003.png deleted file mode 100644 index a8a6913..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00006.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00006.png deleted file mode 100644 index b00f750..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00010.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00010.png deleted file mode 100644 index ac31f5f..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00011.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00011.png deleted file mode 100644 index b0f6c80..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00012.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00012.png deleted file mode 100644 index eb0ade6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00013.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00013.png deleted file mode 100644 index 5204bce..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00013.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00023.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00023.png deleted file mode 100644 index a8a6913..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00023.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00026.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00026.png deleted file mode 100644 index b00f750..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00026.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00100.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00100.png new file mode 100644 index 0000000..216a4ef Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00101.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00101.png new file mode 100644 index 0000000..bcebde4 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00102.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00102.png new file mode 100644 index 0000000..58a376f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_nft/00019.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_nft/00019.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00001.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00001.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00002.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00202.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00002.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00202.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00203.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00203.png new file mode 100644 index 0000000..53e8899 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00203.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00004.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00004.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00003.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00003.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00206.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00206.png new file mode 100644 index 0000000..f7d545b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00206.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00006.png b/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00006.png rename to tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_long_tx/00000.png b/tests/snapshots/nanosp/test_sign_tx_long_tx/00000.png deleted file mode 100644 index 1597f7e..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_long_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_long_tx/00001.png b/tests/snapshots/nanosp/test_sign_tx_long_tx/00001.png deleted file mode 100644 index 8a3938b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_long_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_long_tx/00002.png b/tests/snapshots/nanosp/test_sign_tx_long_tx/00002.png deleted file mode 100644 index 8b3c9da..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_long_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_long_tx/00003.png b/tests/snapshots/nanosp/test_sign_tx_long_tx/00003.png deleted file mode 100644 index 4a2929d..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_long_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00002.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00002.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00004.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00004.png deleted file mode 100644 index 2b9bccd..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00006.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00006.png deleted file mode 100644 index b807f41..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00007.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00007.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00008.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00008.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00010.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00010.png deleted file mode 100644 index 05bd21a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00011.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00011.png deleted file mode 100644 index 50fb1e2..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00012.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00012.png deleted file mode 100644 index 51c42bd..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00022.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00022.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00024.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00024.png deleted file mode 100644 index 2b9bccd..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00100.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00100.png new file mode 100644 index 0000000..27249d7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00101.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00101.png new file mode 100644 index 0000000..7199003 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00020.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00020.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00001.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00001.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00202.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00202.png new file mode 100644 index 0000000..b1ff363 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00003.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00003.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00204.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00204.png new file mode 100644 index 0000000..1a58b12 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00204.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00024.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00024.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00005.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00206.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00005.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00206.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00027.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00207.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00027.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00207.png diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00007.png b/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00300.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_create_delegation/00007.png rename to tests/snapshots/nanosp/test_sign_tx_mint_tokens/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00002.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00002.png deleted file mode 100644 index b71b25b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00004.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00004.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00006.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00006.png deleted file mode 100644 index 58eac55..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00008.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00008.png deleted file mode 100644 index 732826a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00009.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00009.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00009.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00010.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00010.png deleted file mode 100644 index 4738c2b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00010.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00011.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00011.png deleted file mode 100644 index d18d495..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00022.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00022.png deleted file mode 100644 index b71b25b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00032.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00032.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00032.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00034.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00034.png deleted file mode 100644 index 58eac55..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00034.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00100.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00100.png new file mode 100644 index 0000000..05efc73 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00101.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00101.png new file mode 100644 index 0000000..7060383 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00020.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00020.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00001.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00001.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00202.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00202.png new file mode 100644 index 0000000..d596bdf Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00025.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00025.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00021.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00301.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00021.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00301.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00302.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00302.png new file mode 100644 index 0000000..e820252 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00302.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00303.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00303.png new file mode 100644 index 0000000..376ff24 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00303.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00304.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00304.png new file mode 100644 index 0000000..3d1d652 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00304.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00020.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00305.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00020.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00305.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00024.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00306.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00024.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00306.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00037.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00307.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00037.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00307.png diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00005.png b/tests/snapshots/nanosp/test_sign_tx_order_conclude/00400.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_delegation_staking/00005.png rename to tests/snapshots/nanosp/test_sign_tx_order_conclude/00400.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00002.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00002.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00004.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00004.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00005.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00005.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00006.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00006.png deleted file mode 100644 index 6cf46ea..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00008.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00008.png deleted file mode 100644 index b0aa4e8..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00008.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00009.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00009.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00009.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00012.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00012.png deleted file mode 100644 index f766f97..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00022.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00022.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00032.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00032.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00032.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00033.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00033.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00033.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00034.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00034.png deleted file mode 100644 index 6cf46ea..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_order_fill/00034.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00010.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00010.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00011.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00011.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00102.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00102.png new file mode 100644 index 0000000..45ccfa9 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_fill/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00030.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00030.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00021.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_freeze_tokens/00021.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00202.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00202.png new file mode 100644 index 0000000..607670c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_fill/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00035.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00300.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00035.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00003.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00301.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00003.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00301.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00302.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00302.png new file mode 100644 index 0000000..d48537e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_fill/00302.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00023.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00303.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00023.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00303.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00304.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00304.png new file mode 100644 index 0000000..1a58b12 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_order_fill/00304.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00020.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00305.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00020.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00305.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00009.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00306.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00009.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00306.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00037.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00307.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00037.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00307.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00008.png b/tests/snapshots/nanosp/test_sign_tx_order_fill/00400.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00008.png rename to tests/snapshots/nanosp/test_sign_tx_order_fill/00400.png diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00000.png b/tests/snapshots/nanosp/test_sign_tx_refused/00000.png deleted file mode 100644 index 1597f7e..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00000.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00001.png b/tests/snapshots/nanosp/test_sign_tx_refused/00001.png deleted file mode 100644 index 8a3938b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00002.png b/tests/snapshots/nanosp/test_sign_tx_refused/00002.png deleted file mode 100644 index 8b3c9da..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00003.png b/tests/snapshots/nanosp/test_sign_tx_refused/00003.png deleted file mode 100644 index 4a2929d..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00004.png b/tests/snapshots/nanosp/test_sign_tx_refused/00004.png deleted file mode 100644 index 09a1af1..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_refused/00005.png b/tests/snapshots/nanosp/test_sign_tx_refused/00005.png deleted file mode 100644 index 26c6197..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00000.png b/tests/snapshots/nanosp/test_sign_tx_short_tx/00000.png deleted file mode 100644 index 030b884..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_short_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00001.png b/tests/snapshots/nanosp/test_sign_tx_short_tx/00001.png deleted file mode 100644 index 192c2bd..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_short_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00003.png b/tests/snapshots/nanosp/test_sign_tx_short_tx/00003.png deleted file mode 100644 index 57832de..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_short_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00004.png b/tests/snapshots/nanosp/test_sign_tx_short_tx/00004.png deleted file mode 100644 index 7389ab6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_short_tx/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00005.png b/tests/snapshots/nanosp/test_sign_tx_short_tx/00005.png deleted file mode 100644 index 32e7443..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_short_tx/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00002.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00002.png deleted file mode 100644 index 0378fc6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00011.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00011.png deleted file mode 100644 index 75337cb..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00012.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00012.png deleted file mode 100644 index 0378fc6..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_transfer/00012.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00010.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00010.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_short_tx/00002.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_short_tx/00002.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00102.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00102.png new file mode 100644 index 0000000..c759d9b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_transfer/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00030.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00030.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00004.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00004.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00104.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00005.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00105.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00005.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00105.png diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00006.png b/tests/snapshots/nanosp/test_sign_tx_transfer/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00006.png rename to tests/snapshots/nanosp/test_sign_tx_transfer/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00002.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00004.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00004.png deleted file mode 100644 index fb41633..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00005.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00006.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00022.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00010.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00010.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00011.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00011.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00035.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00035.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00007.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00007.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00202.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00003.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00003.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00024.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00024.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00025.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00025.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_long_tx/00004.png b/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00300.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_long_tx/00004.png rename to tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00002.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00003.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00003.png deleted file mode 100644 index 8973d80..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00005.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00005.png deleted file mode 100644 index fce7d0b..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00006.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00007.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00007.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00007.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00022.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00024.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00024.png deleted file mode 100644 index 8973d80..0000000 Binary files a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00010.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00100.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00010.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00011.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00011.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00013.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00013.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00021.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00021.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00202.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00020.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00020.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00204.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00204.png new file mode 100644 index 0000000..10fa236 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00204.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00004.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00004.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00205.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00026.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00206.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00026.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00206.png diff --git a/tests/snapshots/nanox/test_sign_tx_short_tx/00004.png b/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00300.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_short_tx/00004.png rename to tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00300.png diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00000.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00000.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_delegation_staking/00000.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00000.png diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00100.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00100.png new file mode 100644 index 0000000..e49b5a9 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00101.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00101.png new file mode 100644 index 0000000..eeca286 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00102.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00102.png new file mode 100644 index 0000000..d3d4399 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00103.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00103.png new file mode 100644 index 0000000..e4ce494 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00023.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00023.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00104.png diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00105.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00105.png new file mode 100644 index 0000000..ca25279 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00105.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00015.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00106.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00015.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00106.png diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00006.png b/tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_transfer/00006.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_input_and_commitment/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00000.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00100.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00100.png new file mode 100644 index 0000000..8eb7eca Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00100.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00101.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00101.png new file mode 100644 index 0000000..94cbe16 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00101.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00102.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00102.png new file mode 100644 index 0000000..57f8edc Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00102.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00103.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00103.png new file mode 100644 index 0000000..adb48cb Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00103.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00104.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00104.png new file mode 100644 index 0000000..bac888b Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00104.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00105.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00105.png new file mode 100644 index 0000000..ff2c2a8 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00105.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00106.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00106.png new file mode 100644 index 0000000..9f6dc8d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00106.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00107.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00107.png new file mode 100644 index 0000000..8a490a4 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00107.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00108.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00108.png new file mode 100644 index 0000000..18123a5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00108.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00109.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00109.png new file mode 100644 index 0000000..615928e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00109.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00110.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00110.png new file mode 100644 index 0000000..214e45d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00110.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00111.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00111.png new file mode 100644 index 0000000..1da0b67 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00111.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00112.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00112.png new file mode 100644 index 0000000..43ae4fb Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00112.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00113.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00113.png new file mode 100644 index 0000000..06534a7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00113.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00114.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00114.png new file mode 100644 index 0000000..3cfd3b1 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00114.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00115.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00115.png new file mode 100644 index 0000000..93af868 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00115.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00116.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00116.png new file mode 100644 index 0000000..f4ec1f4 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00116.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00117.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00117.png new file mode 100644 index 0000000..3f4b57f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00117.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00118.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00118.png new file mode 100644 index 0000000..175dcbd Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00118.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00020.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00119.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00020.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_output/00119.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00020.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00120.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_nft/00020.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_output/00120.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00021.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00121.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_nft/00021.png rename to tests/snapshots/nanosp/test_sign_tx_with_large_output/00121.png diff --git a/tests/snapshots/nanosp/test_sign_tx_with_large_output/00200.png b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_with_large_output/00200.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_without_outputs/00000.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00010.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_freeze_tokens/00010.png rename to tests/snapshots/nanosp/test_sign_tx_without_outputs/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00011.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00101.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_freeze_tokens/00011.png rename to tests/snapshots/nanosp/test_sign_tx_without_outputs/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00023.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00200.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00023.png rename to tests/snapshots/nanosp/test_sign_tx_without_outputs/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_mint_tokens/00026.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_mint_tokens/00026.png rename to tests/snapshots/nanosp/test_sign_tx_without_outputs/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00025.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00202.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_freeze_tokens/00025.png rename to tests/snapshots/nanosp/test_sign_tx_without_outputs/00202.png diff --git a/tests/snapshots/nanosp/test_sign_tx_without_outputs/00300.png b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_without_outputs/00300.png differ diff --git a/tests/snapshots/nanox/test_app_mainmenu/00003.png b/tests/snapshots/nanox/test_app_mainmenu/00003.png deleted file mode 100644 index f265d69..0000000 Binary files a/tests/snapshots/nanox/test_app_mainmenu/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00000.png b/tests/snapshots/nanox/test_sign_large_message/00000.png new file mode 100644 index 0000000..2e4d511 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00001.png b/tests/snapshots/nanox/test_sign_large_message/00001.png new file mode 100644 index 0000000..602c22a Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00002.png b/tests/snapshots/nanox/test_sign_large_message/00002.png new file mode 100644 index 0000000..305308f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00003.png b/tests/snapshots/nanox/test_sign_large_message/00003.png new file mode 100644 index 0000000..7802e92 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00004.png b/tests/snapshots/nanox/test_sign_large_message/00004.png new file mode 100644 index 0000000..40bdb70 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00005.png b/tests/snapshots/nanox/test_sign_large_message/00005.png new file mode 100644 index 0000000..850225e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00005.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00006.png b/tests/snapshots/nanox/test_sign_large_message/00006.png new file mode 100644 index 0000000..cec141b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00007.png b/tests/snapshots/nanox/test_sign_large_message/00007.png new file mode 100644 index 0000000..36eb31d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00007.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00008.png b/tests/snapshots/nanox/test_sign_large_message/00008.png new file mode 100644 index 0000000..df753a1 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00008.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00009.png b/tests/snapshots/nanox/test_sign_large_message/00009.png new file mode 100644 index 0000000..d5b841e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00009.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00010.png b/tests/snapshots/nanox/test_sign_large_message/00010.png new file mode 100644 index 0000000..f5e85c3 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00010.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00011.png b/tests/snapshots/nanox/test_sign_large_message/00011.png new file mode 100644 index 0000000..d22ac2d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00011.png differ diff --git a/tests/snapshots/nanox/test_sign_large_message/00012.png b/tests/snapshots/nanox/test_sign_large_message/00012.png new file mode 100644 index 0000000..55bb5c8 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_large_message/00012.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_pkh/00005.png b/tests/snapshots/nanox/test_sign_large_message/00013.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_message_pkh/00005.png rename to tests/snapshots/nanox/test_sign_large_message/00013.png diff --git a/tests/snapshots/nanox/test_sign_message/00001.png b/tests/snapshots/nanox/test_sign_message/00001.png index 8cae4d6..602c22a 100644 Binary files a/tests/snapshots/nanox/test_sign_message/00001.png and b/tests/snapshots/nanox/test_sign_message/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message/00002.png b/tests/snapshots/nanox/test_sign_message/00002.png index 602c22a..305308f 100644 Binary files a/tests/snapshots/nanox/test_sign_message/00002.png and b/tests/snapshots/nanox/test_sign_message/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_message/00003.png b/tests/snapshots/nanox/test_sign_message/00003.png index 305308f..3617b8d 100644 Binary files a/tests/snapshots/nanox/test_sign_message/00003.png and b/tests/snapshots/nanox/test_sign_message/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_message/00004.png b/tests/snapshots/nanox/test_sign_message/00004.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanox/test_sign_message/00004.png and b/tests/snapshots/nanox/test_sign_message/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_message/00005.png b/tests/snapshots/nanox/test_sign_message/00005.png index 55bb5c8..ab20bae 100644 Binary files a/tests/snapshots/nanox/test_sign_message/00005.png and b/tests/snapshots/nanox/test_sign_message/00005.png differ diff --git a/tests/snapshots/nanox/test_sign_message/00006.png b/tests/snapshots/nanox/test_sign_message/00006.png deleted file mode 100644 index ab20bae..0000000 Binary files a/tests/snapshots/nanox/test_sign_message/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_message_pkh/00001.png b/tests/snapshots/nanox/test_sign_message_pkh/00001.png index 8cae4d6..208f5d8 100644 Binary files a/tests/snapshots/nanox/test_sign_message_pkh/00001.png and b/tests/snapshots/nanox/test_sign_message_pkh/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message_pkh/00002.png b/tests/snapshots/nanox/test_sign_message_pkh/00002.png index 208f5d8..3617b8d 100644 Binary files a/tests/snapshots/nanox/test_sign_message_pkh/00002.png and b/tests/snapshots/nanox/test_sign_message_pkh/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_message_pkh/00003.png b/tests/snapshots/nanox/test_sign_message_pkh/00003.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanox/test_sign_message_pkh/00003.png and b/tests/snapshots/nanox/test_sign_message_pkh/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_message_pkh/00004.png b/tests/snapshots/nanox/test_sign_message_pkh/00004.png index 55bb5c8..ab20bae 100644 Binary files a/tests/snapshots/nanox/test_sign_message_pkh/00004.png and b/tests/snapshots/nanox/test_sign_message_pkh/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_message_pkh/00005.png b/tests/snapshots/nanox/test_sign_message_pkh/00005.png deleted file mode 100644 index ab20bae..0000000 Binary files a/tests/snapshots/nanox/test_sign_message_pkh/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00001.png b/tests/snapshots/nanox/test_sign_message_refused/00001.png index 8cae4d6..602c22a 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00001.png and b/tests/snapshots/nanox/test_sign_message_refused/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00002.png b/tests/snapshots/nanox/test_sign_message_refused/00002.png index 602c22a..305308f 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00002.png and b/tests/snapshots/nanox/test_sign_message_refused/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00003.png b/tests/snapshots/nanox/test_sign_message_refused/00003.png index 305308f..3617b8d 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00003.png and b/tests/snapshots/nanox/test_sign_message_refused/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00004.png b/tests/snapshots/nanox/test_sign_message_refused/00004.png index 3617b8d..55bb5c8 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00004.png and b/tests/snapshots/nanox/test_sign_message_refused/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00005.png b/tests/snapshots/nanox/test_sign_message_refused/00005.png index 55bb5c8..12caa58 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00005.png and b/tests/snapshots/nanox/test_sign_message_refused/00005.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00006.png b/tests/snapshots/nanox/test_sign_message_refused/00006.png index 12caa58..d917d19 100644 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00006.png and b/tests/snapshots/nanox/test_sign_message_refused/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_message_refused/00007.png b/tests/snapshots/nanox/test_sign_message_refused/00007.png deleted file mode 100644 index d917d19..0000000 Binary files a/tests/snapshots/nanox/test_sign_message_refused/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00001.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00002.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00004.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00004.png deleted file mode 100644 index 2fca943..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00005.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00010.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00010.png deleted file mode 100644 index c408134..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00011.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00011.png deleted file mode 100644 index fc6fca6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00012.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00012.png deleted file mode 100644 index e2577f8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00013.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00013.png deleted file mode 100644 index aa75038..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00021.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00022.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00024.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00024.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00100.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00100.png new file mode 100644 index 0000000..15fea9d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00101.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00101.png new file mode 100644 index 0000000..bc691a7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00102.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00102.png new file mode 100644 index 0000000..28ee9c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00103.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00103.png new file mode 100644 index 0000000..9832913 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00020.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_authority/00020.png rename to tests/snapshots/nanox/test_sign_tx_change_token_authority/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00001.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00001.png rename to tests/snapshots/nanox/test_sign_tx_change_token_authority/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00202.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00023.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_authority/00023.png rename to tests/snapshots/nanox/test_sign_tx_change_token_authority/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00005.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00005.png rename to tests/snapshots/nanox/test_sign_tx_change_token_authority/00204.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00025.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00205.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_authority/00025.png rename to tests/snapshots/nanox/test_sign_tx_change_token_authority/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00300.png b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_authority/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00001.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00002.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00003.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00003.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00004.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00004.png deleted file mode 100644 index c7d5676..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00005.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00010.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00010.png deleted file mode 100644 index de18f19..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00011.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00011.png deleted file mode 100644 index 39359b8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00012.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00012.png deleted file mode 100644 index c335313..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00021.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00022.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00024.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00024.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00100.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00100.png new file mode 100644 index 0000000..196af3c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00101.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00101.png new file mode 100644 index 0000000..08f05af Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00102.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00102.png new file mode 100644 index 0000000..5057eb0 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00020.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00020.png rename to tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00021.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00021.png rename to tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00202.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00023.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00023.png rename to tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00025.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00025.png rename to tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00204.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00025.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00205.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00025.png rename to tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00300.png b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_change_token_metadata_uri/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00001.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00001.png deleted file mode 100644 index 2ce4f7e..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00002.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00002.png deleted file mode 100644 index 3169a43..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00003.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00003.png deleted file mode 100644 index 4100b0b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00004.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00004.png deleted file mode 100644 index 46b368c..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00005.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00005.png deleted file mode 100644 index 0f6ca54..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00006.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00006.png deleted file mode 100644 index 32a3fd1..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00011.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00011.png deleted file mode 100644 index 59d0e80..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00012.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00012.png deleted file mode 100644 index 3d01046..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00013.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00013.png deleted file mode 100644 index f62cce2..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00015.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00015.png deleted file mode 100644 index 0f6ca54..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00015.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00016.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00016.png deleted file mode 100644 index 17cf916..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_delegation/00016.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00010.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_create_delegation/00010.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00011.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00011.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00012.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00012.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00013.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00013.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00103.png diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00014.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00104.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_create_delegation/00014.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00104.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00006.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00105.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00006.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00105.png diff --git a/tests/snapshots/nanosp/test_sign_tx_create_delegation/00016.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00106.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_create_delegation/00016.png rename to tests/snapshots/nanox/test_sign_tx_create_delegation/00106.png diff --git a/tests/snapshots/nanox/test_sign_tx_create_delegation/00200.png b/tests/snapshots/nanox/test_sign_tx_create_delegation/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_delegation/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00001.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00001.png deleted file mode 100644 index 3fbfcda..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00002.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00002.png deleted file mode 100644 index dc3f263..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00003.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00003.png deleted file mode 100644 index dd49ec2..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00004.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00004.png deleted file mode 100644 index 7623766..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00005.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00005.png deleted file mode 100644 index 0562b8b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00006.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00006.png deleted file mode 100644 index 9880fbf..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00007.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00007.png deleted file mode 100644 index 5d19c53..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00008.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00008.png deleted file mode 100644 index 7184c47..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00008.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00009.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00009.png deleted file mode 100644 index f278bff..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00009.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00010.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00010.png deleted file mode 100644 index 139058c..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00011.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00011.png deleted file mode 100644 index dc3f263..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00012.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00012.png deleted file mode 100644 index dd49ec2..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00013.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00013.png deleted file mode 100644 index 7623766..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00014.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00014.png deleted file mode 100644 index 0562b8b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00015.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00015.png deleted file mode 100644 index 9880fbf..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00015.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00016.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00016.png deleted file mode 100644 index 5d19c53..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00016.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00017.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00017.png deleted file mode 100644 index 7184c47..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00017.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00018.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00018.png deleted file mode 100644 index f278bff..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00018.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00019.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00019.png deleted file mode 100644 index 06704db..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00019.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00021.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00021.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00100.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00100.png new file mode 100644 index 0000000..ad24691 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00101.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00101.png new file mode 100644 index 0000000..bd7a27e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00102.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00102.png new file mode 100644 index 0000000..cb8a713 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00103.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00103.png new file mode 100644 index 0000000..af79c8c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00104.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00104.png new file mode 100644 index 0000000..38c565f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00105.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00105.png new file mode 100644 index 0000000..bd5c339 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00105.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00106.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00106.png new file mode 100644 index 0000000..b1cd9fe Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00106.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00107.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00107.png new file mode 100644 index 0000000..e35ffb0 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00107.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00108.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00108.png new file mode 100644 index 0000000..42713e3 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00108.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00109.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00109.png new file mode 100644 index 0000000..5418fd7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00109.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00020.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00110.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_create_stake_pool/00020.png rename to tests/snapshots/nanox/test_sign_tx_create_stake_pool/00110.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00007.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00111.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00007.png rename to tests/snapshots/nanox/test_sign_tx_create_stake_pool/00111.png diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00022.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00112.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_create_stake_pool/00022.png rename to tests/snapshots/nanox/test_sign_tx_create_stake_pool/00112.png diff --git a/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00200.png b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_create_stake_pool/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegate_staking/00000.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00010.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_delegation_staking/00010.png rename to tests/snapshots/nanox/test_sign_tx_delegate_staking/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_delegate_staking/00101.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00101.png new file mode 100644 index 0000000..722145c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00012.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00102.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_delegation_staking/00012.png rename to tests/snapshots/nanox/test_sign_tx_delegate_staking/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_delegation_staking/00013.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_delegation_staking/00013.png rename to tests/snapshots/nanox/test_sign_tx_delegate_staking/00103.png diff --git a/tests/snapshots/nanox/test_sign_tx_delegate_staking/00104.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00104.png new file mode 100644 index 0000000..e0ad1f1 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegate_staking/00200.png b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_delegate_staking/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00001.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00001.png deleted file mode 100644 index 3645243..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00002.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00002.png deleted file mode 100644 index 2df9d67..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00003.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00003.png deleted file mode 100644 index 0623b1b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00004.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00004.png deleted file mode 100644 index bbd76c8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00011.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00011.png deleted file mode 100644 index 52979b5..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00013.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00013.png deleted file mode 100644 index 0623b1b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00014.png b/tests/snapshots/nanox/test_sign_tx_delegation_staking/00014.png deleted file mode 100644 index c6836c8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_delegation_staking/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00002.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00003.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00003.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00004.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00004.png deleted file mode 100644 index bc9b1a8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00005.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00022.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00024.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00024.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00100.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00100.png new file mode 100644 index 0000000..eaa64e5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00101.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00101.png new file mode 100644 index 0000000..351a884 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00020.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_freeze_tokens/00020.png rename to tests/snapshots/nanox/test_sign_tx_freeze_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00001.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00001.png rename to tests/snapshots/nanox/test_sign_tx_freeze_tokens/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00202.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00023.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_freeze_tokens/00023.png rename to tests/snapshots/nanox/test_sign_tx_freeze_tokens/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00036.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00036.png rename to tests/snapshots/nanox/test_sign_tx_freeze_tokens/00204.png diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00205.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00205.png new file mode 100644 index 0000000..567675f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00205.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00300.png b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_freeze_tokens/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00001.png b/tests/snapshots/nanox/test_sign_tx_htlc/00001.png deleted file mode 100644 index aab0aed..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00002.png b/tests/snapshots/nanox/test_sign_tx_htlc/00002.png deleted file mode 100644 index f113d41..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00003.png b/tests/snapshots/nanox/test_sign_tx_htlc/00003.png deleted file mode 100644 index 195e6f3..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00004.png b/tests/snapshots/nanox/test_sign_tx_htlc/00004.png deleted file mode 100644 index 778f66f..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00005.png b/tests/snapshots/nanox/test_sign_tx_htlc/00005.png deleted file mode 100644 index 0d5d509..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00006.png b/tests/snapshots/nanox/test_sign_tx_htlc/00006.png deleted file mode 100644 index 5fc12d1..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00007.png b/tests/snapshots/nanox/test_sign_tx_htlc/00007.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00008.png b/tests/snapshots/nanox/test_sign_tx_htlc/00008.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00008.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00009.png b/tests/snapshots/nanox/test_sign_tx_htlc/00009.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00009.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00011.png b/tests/snapshots/nanox/test_sign_tx_htlc/00011.png deleted file mode 100644 index f113d41..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00012.png b/tests/snapshots/nanox/test_sign_tx_htlc/00012.png deleted file mode 100644 index 195e6f3..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00013.png b/tests/snapshots/nanox/test_sign_tx_htlc/00013.png deleted file mode 100644 index 778f66f..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00014.png b/tests/snapshots/nanox/test_sign_tx_htlc/00014.png deleted file mode 100644 index 0d5d509..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00015.png b/tests/snapshots/nanox/test_sign_tx_htlc/00015.png deleted file mode 100644 index 5fc12d1..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00015.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00021.png b/tests/snapshots/nanox/test_sign_tx_htlc/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00022.png b/tests/snapshots/nanox/test_sign_tx_htlc/00022.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00024.png b/tests/snapshots/nanox/test_sign_tx_htlc/00024.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_htlc/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00010.png b/tests/snapshots/nanox/test_sign_tx_htlc/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_htlc/00010.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00011.png b/tests/snapshots/nanox/test_sign_tx_htlc/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00011.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00101.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00012.png b/tests/snapshots/nanox/test_sign_tx_htlc/00102.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00012.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00102.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00013.png b/tests/snapshots/nanox/test_sign_tx_htlc/00103.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00013.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_htlc/00014.png b/tests/snapshots/nanox/test_sign_tx_htlc/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_htlc/00014.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00104.png diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00105.png b/tests/snapshots/nanox/test_sign_tx_htlc/00105.png new file mode 100644 index 0000000..9949b8d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_htlc/00105.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00020.png b/tests/snapshots/nanox/test_sign_tx_htlc/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_htlc/00020.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00021.png b/tests/snapshots/nanox/test_sign_tx_htlc/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00021.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00202.png b/tests/snapshots/nanox/test_sign_tx_htlc/00202.png new file mode 100644 index 0000000..607670c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_htlc/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00023.png b/tests/snapshots/nanox/test_sign_tx_htlc/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_htlc/00023.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00203.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00007.png b/tests/snapshots/nanox/test_sign_tx_htlc/00204.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00007.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00204.png diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00025.png b/tests/snapshots/nanox/test_sign_tx_htlc/00205.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_htlc/00025.png rename to tests/snapshots/nanox/test_sign_tx_htlc/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_htlc/00300.png b/tests/snapshots/nanox/test_sign_tx_htlc/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_htlc/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00001.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00001.png deleted file mode 100644 index 00051f8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00002.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00002.png deleted file mode 100644 index c09832c..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00003.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00003.png deleted file mode 100644 index 419f5f0..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00004.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00004.png deleted file mode 100644 index 26db145..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00005.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00005.png deleted file mode 100644 index 060d61b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00006.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00006.png deleted file mode 100644 index 0f6ca54..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00007.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00007.png deleted file mode 100644 index d3ca23a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00013.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00013.png deleted file mode 100644 index 6d1bc9a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00014.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00014.png deleted file mode 100644 index 4c43c01..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00016.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00016.png deleted file mode 100644 index 0f6ca54..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00016.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00010.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00010.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00011.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00101.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00011.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00101.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00012.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00102.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00012.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00102.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00103.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00103.png new file mode 100644 index 0000000..77eedd9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00104.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00104.png new file mode 100644 index 0000000..f589bbf Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00015.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00105.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00015.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00105.png diff --git a/tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00016.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00106.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_issue_fungible_token/00016.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00106.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00017.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00107.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00017.png rename to tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00107.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00200.png b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_fungible_token/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00001.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00001.png deleted file mode 100644 index 2318573..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00002.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00002.png deleted file mode 100644 index d84fdcd..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00003.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00003.png deleted file mode 100644 index 415b46b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00004.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00004.png deleted file mode 100644 index 7fb1f67..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00005.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00005.png deleted file mode 100644 index e14acb6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00006.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00006.png deleted file mode 100644 index 03f61f6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00007.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00007.png deleted file mode 100644 index f678edc..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00008.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00008.png deleted file mode 100644 index 0a262d5..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00008.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00009.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00009.png deleted file mode 100644 index 1a586fb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00009.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00010.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00010.png deleted file mode 100644 index 84ff3f7..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00011.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00011.png deleted file mode 100644 index 3fdec7f..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00012.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00012.png deleted file mode 100644 index a9bd3e2..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00013.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00013.png deleted file mode 100644 index b9a3aba..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00013.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00014.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00014.png deleted file mode 100644 index b69697c..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00015.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00015.png deleted file mode 100644 index 651a3f4..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00015.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00016.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00016.png deleted file mode 100644 index 19e1140..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00016.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00017.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00017.png deleted file mode 100644 index 95bb380..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00017.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00018.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00018.png deleted file mode 100644 index 4cf446c..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_issue_nft/00018.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00100.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00100.png new file mode 100644 index 0000000..8b7b71f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00101.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00101.png new file mode 100644 index 0000000..9d40b0b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00102.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00102.png new file mode 100644 index 0000000..64c4618 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00103.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00103.png new file mode 100644 index 0000000..2400405 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00104.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00104.png new file mode 100644 index 0000000..2f750b3 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00105.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00105.png new file mode 100644 index 0000000..e3ef4c1 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00105.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00106.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00106.png new file mode 100644 index 0000000..bc9c4a5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00106.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00107.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00107.png new file mode 100644 index 0000000..77dec68 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00107.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00108.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00108.png new file mode 100644 index 0000000..6d7bef4 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00108.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00109.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00109.png new file mode 100644 index 0000000..8bf8d9b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00109.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00019.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00110.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_issue_nft/00019.png rename to tests/snapshots/nanox/test_sign_tx_issue_nft/00110.png diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00111.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00111.png new file mode 100644 index 0000000..af149c9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00111.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00112.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00112.png new file mode 100644 index 0000000..8a6f6ed Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00112.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_issue_nft/00200.png b/tests/snapshots/nanox/test_sign_tx_issue_nft/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_issue_nft/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00001.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00001.png deleted file mode 100644 index a7b61f1..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00002.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00002.png deleted file mode 100644 index c31d61b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00003.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00003.png deleted file mode 100644 index 291da46..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00004.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00004.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00005.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00005.png deleted file mode 100644 index 62b8f91..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00010.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00010.png deleted file mode 100644 index ac31f5f..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00011.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00011.png deleted file mode 100644 index b0f6c80..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00012.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00012.png deleted file mode 100644 index eb0ade6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00021.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00021.png deleted file mode 100644 index 7a9b805..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00022.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00022.png deleted file mode 100644 index 342974f..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00023.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00023.png deleted file mode 100644 index a8a6913..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00023.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00025.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00025.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00025.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00026.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00026.png deleted file mode 100644 index b00f750..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00026.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00100.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00100.png new file mode 100644 index 0000000..216a4ef Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00101.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00101.png new file mode 100644 index 0000000..bcebde4 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00102.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00102.png new file mode 100644 index 0000000..58a376f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00020.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00020.png rename to tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00021.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00021.png rename to tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00201.png diff --git a/tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00022.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00202.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_lock_then_transfer/00022.png rename to tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00202.png diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00203.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00203.png new file mode 100644 index 0000000..53e8899 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00203.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00024.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00204.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00024.png rename to tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00204.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00036.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00036.png rename to tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00206.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00206.png new file mode 100644 index 0000000..f7d545b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00206.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00300.png b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_lock_then_transfer/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_long_tx/00000.png b/tests/snapshots/nanox/test_sign_tx_long_tx/00000.png deleted file mode 100644 index 1597f7e..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_long_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_long_tx/00001.png b/tests/snapshots/nanox/test_sign_tx_long_tx/00001.png deleted file mode 100644 index 8a3938b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_long_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_long_tx/00002.png b/tests/snapshots/nanox/test_sign_tx_long_tx/00002.png deleted file mode 100644 index 8b3c9da..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_long_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_long_tx/00003.png b/tests/snapshots/nanox/test_sign_tx_long_tx/00003.png deleted file mode 100644 index 4a2929d..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_long_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00001.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00002.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00002.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00003.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00003.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00004.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00004.png deleted file mode 100644 index 2b9bccd..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00006.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00006.png deleted file mode 100644 index b807f41..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00007.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00007.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00010.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00010.png deleted file mode 100644 index 05bd21a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00011.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00011.png deleted file mode 100644 index 50fb1e2..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00012.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00012.png deleted file mode 100644 index 51c42bd..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00021.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00022.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00022.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00023.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00023.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00024.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00024.png deleted file mode 100644 index 2b9bccd..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00100.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00100.png new file mode 100644 index 0000000..27249d7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00101.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00101.png new file mode 100644 index 0000000..7199003 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00020.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_mint_tokens/00020.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00031.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00031.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00202.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00202.png new file mode 100644 index 0000000..b1ff363 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00202.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00005.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00203.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00005.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00203.png diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00204.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00204.png new file mode 100644 index 0000000..1a58b12 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00204.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00025.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00205.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_mint_tokens/00025.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00005.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00206.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_mint_tokens/00005.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00206.png diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00027.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00207.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_mint_tokens/00027.png rename to tests/snapshots/nanox/test_sign_tx_mint_tokens/00207.png diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00300.png b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_mint_tokens/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00001.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00002.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00002.png deleted file mode 100644 index b71b25b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00003.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00003.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00004.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00004.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00005.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00005.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00006.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00006.png deleted file mode 100644 index 58eac55..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00007.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00007.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00008.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00008.png deleted file mode 100644 index 732826a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00008.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00009.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00009.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00009.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00010.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00010.png deleted file mode 100644 index 4738c2b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00010.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00011.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00011.png deleted file mode 100644 index d18d495..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00021.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00022.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00022.png deleted file mode 100644 index b71b25b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00031.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00031.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00031.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00032.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00032.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00032.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00033.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00033.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00033.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00034.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00034.png deleted file mode 100644 index 58eac55..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00034.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00036.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00036.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_conclude/00036.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00100.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00100.png new file mode 100644 index 0000000..05efc73 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00101.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00101.png new file mode 100644 index 0000000..7060383 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00020.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_conclude/00020.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00001.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00202.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00202.png new file mode 100644 index 0000000..d596bdf Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00030.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00300.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_conclude/00030.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00003.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00301.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00003.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00301.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00302.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00302.png new file mode 100644 index 0000000..e820252 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00302.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00303.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00303.png new file mode 100644 index 0000000..376ff24 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00303.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00304.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00304.png new file mode 100644 index 0000000..3d1d652 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00304.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00035.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00305.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_conclude/00035.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00305.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00003.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00306.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00003.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00306.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00037.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00307.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_conclude/00037.png rename to tests/snapshots/nanox/test_sign_tx_order_conclude/00307.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_conclude/00400.png b/tests/snapshots/nanox/test_sign_tx_order_conclude/00400.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_conclude/00400.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00001.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00002.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00002.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00003.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00003.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00004.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00004.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00005.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00005.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00006.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00006.png deleted file mode 100644 index 6cf46ea..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00007.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00007.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00007.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00008.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00008.png deleted file mode 100644 index b0aa4e8..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00008.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00009.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00009.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00009.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00012.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00012.png deleted file mode 100644 index f766f97..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00021.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00022.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00022.png deleted file mode 100644 index 62b7685..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00031.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00031.png deleted file mode 100644 index ec1e8cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00031.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00032.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00032.png deleted file mode 100644 index 5d5329a..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00032.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00033.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00033.png deleted file mode 100644 index f12db18..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00033.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00034.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00034.png deleted file mode 100644 index 6cf46ea..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00034.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00036.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00036.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_order_fill/00036.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00010.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00010.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00011.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00101.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00011.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00101.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00102.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00102.png new file mode 100644 index 0000000..45ccfa9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_fill/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00020.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00020.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00021.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00202.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00202.png new file mode 100644 index 0000000..607670c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_fill/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00030.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00300.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00030.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00300.png diff --git a/tests/snapshots/nanosp/test_sign_tx_order_fill/00031.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00301.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_fill/00031.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00301.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00302.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00302.png new file mode 100644 index 0000000..d48537e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_fill/00302.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_order_conclude/00033.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00303.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_order_conclude/00033.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00303.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00304.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00304.png new file mode 100644 index 0000000..1a58b12 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_fill/00304.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00035.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00305.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00035.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00305.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00024.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00306.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unfreeze_tokens/00024.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00306.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00037.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00307.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_order_fill/00037.png rename to tests/snapshots/nanox/test_sign_tx_order_fill/00307.png diff --git a/tests/snapshots/nanox/test_sign_tx_order_fill/00400.png b/tests/snapshots/nanox/test_sign_tx_order_fill/00400.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_order_fill/00400.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00000.png b/tests/snapshots/nanox/test_sign_tx_refused/00000.png deleted file mode 100644 index 1597f7e..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00000.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00001.png b/tests/snapshots/nanox/test_sign_tx_refused/00001.png deleted file mode 100644 index 8a3938b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00002.png b/tests/snapshots/nanox/test_sign_tx_refused/00002.png deleted file mode 100644 index 8b3c9da..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00003.png b/tests/snapshots/nanox/test_sign_tx_refused/00003.png deleted file mode 100644 index 4a2929d..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00004.png b/tests/snapshots/nanox/test_sign_tx_refused/00004.png deleted file mode 100644 index 09a1af1..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00005.png b/tests/snapshots/nanox/test_sign_tx_refused/00005.png deleted file mode 100644 index 26c6197..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_short_tx/00000.png b/tests/snapshots/nanox/test_sign_tx_short_tx/00000.png deleted file mode 100644 index 1597f7e..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_short_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_short_tx/00001.png b/tests/snapshots/nanox/test_sign_tx_short_tx/00001.png deleted file mode 100644 index ce243c5..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_short_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_short_tx/00002.png b/tests/snapshots/nanox/test_sign_tx_short_tx/00002.png deleted file mode 100644 index 8b3c9da..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_short_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_short_tx/00003.png b/tests/snapshots/nanox/test_sign_tx_short_tx/00003.png deleted file mode 100644 index 4a2929d..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_short_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00001.png b/tests/snapshots/nanox/test_sign_tx_transfer/00001.png deleted file mode 100644 index 192c2bd..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00002.png b/tests/snapshots/nanox/test_sign_tx_transfer/00002.png deleted file mode 100644 index 75337cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00003.png b/tests/snapshots/nanox/test_sign_tx_transfer/00003.png deleted file mode 100644 index 0378fc6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00004.png b/tests/snapshots/nanox/test_sign_tx_transfer/00004.png deleted file mode 100644 index 639af51..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00005.png b/tests/snapshots/nanox/test_sign_tx_transfer/00005.png deleted file mode 100644 index 6e3cb60..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00011.png b/tests/snapshots/nanox/test_sign_tx_transfer/00011.png deleted file mode 100644 index 75337cb..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00012.png b/tests/snapshots/nanox/test_sign_tx_transfer/00012.png deleted file mode 100644 index 0378fc6..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00012.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00014.png b/tests/snapshots/nanox/test_sign_tx_transfer/00014.png deleted file mode 100644 index 639af51..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_transfer/00014.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00010.png b/tests/snapshots/nanox/test_sign_tx_transfer/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_transfer/00010.png rename to tests/snapshots/nanox/test_sign_tx_transfer/00100.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00001.png b/tests/snapshots/nanox/test_sign_tx_transfer/00101.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00001.png rename to tests/snapshots/nanox/test_sign_tx_transfer/00101.png diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00102.png b/tests/snapshots/nanox/test_sign_tx_transfer/00102.png new file mode 100644 index 0000000..c759d9b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_transfer/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00013.png b/tests/snapshots/nanox/test_sign_tx_transfer/00103.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_transfer/00013.png rename to tests/snapshots/nanox/test_sign_tx_transfer/00103.png diff --git a/tests/snapshots/nanosp/test_sign_tx_transfer/00014.png b/tests/snapshots/nanox/test_sign_tx_transfer/00104.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_transfer/00014.png rename to tests/snapshots/nanox/test_sign_tx_transfer/00104.png diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00015.png b/tests/snapshots/nanox/test_sign_tx_transfer/00105.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_transfer/00015.png rename to tests/snapshots/nanox/test_sign_tx_transfer/00105.png diff --git a/tests/snapshots/nanox/test_sign_tx_transfer/00200.png b/tests/snapshots/nanox/test_sign_tx_transfer/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_transfer/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00002.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00003.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00003.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00004.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00004.png deleted file mode 100644 index fb41633..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00005.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00005.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00022.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00024.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00024.png deleted file mode 100644 index 2737bf9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00010.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00010.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00011.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00101.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00011.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00101.png diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00020.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00020.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00001.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00202.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00023.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00023.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00203.png diff --git a/tests/snapshots/nanox/test_sign_tx_change_token_authority/00003.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00204.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_change_token_authority/00003.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00204.png diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00025.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00205.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00025.png rename to tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00300.png b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_unfreeze_tokens/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00001.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00001.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00002.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00002.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00003.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00003.png deleted file mode 100644 index 8973d80..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00004.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00004.png deleted file mode 100644 index 8ed052d..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00005.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00005.png deleted file mode 100644 index fce7d0b..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00006.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00006.png deleted file mode 100644 index b2e3594..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00006.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00021.png deleted file mode 100644 index f8e1b29..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00022.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00022.png deleted file mode 100644 index 31b2df9..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00022.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00024.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00024.png deleted file mode 100644 index 8973d80..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00024.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00025.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00025.png deleted file mode 100644 index 8ed052d..0000000 Binary files a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00025.png and /dev/null differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00010.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00100.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unmint_tokens/00010.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00100.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00011.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00101.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unmint_tokens/00011.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00101.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00020.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00200.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unmint_tokens/00020.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00200.png diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00021.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00201.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00021.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00202.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00202.png new file mode 100644 index 0000000..85319c5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00023.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00203.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unmint_tokens/00023.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00203.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00204.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00204.png new file mode 100644 index 0000000..10fa236 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00204.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00025.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00205.png similarity index 100% rename from tests/snapshots/nanosp/test_sign_tx_unmint_tokens/00025.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00205.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00026.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00206.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_unmint_tokens/00026.png rename to tests/snapshots/nanox/test_sign_tx_unmint_tokens/00206.png diff --git a/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00300.png b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_unmint_tokens/00300.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00000.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00100.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00100.png new file mode 100644 index 0000000..e49b5a9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00101.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00101.png new file mode 100644 index 0000000..eeca286 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00102.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00102.png new file mode 100644 index 0000000..d3d4399 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00103.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00103.png new file mode 100644 index 0000000..e4ce494 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00104.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00104.png new file mode 100644 index 0000000..11e1d3f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00105.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00105.png new file mode 100644 index 0000000..ca25279 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00105.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00106.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00106.png new file mode 100644 index 0000000..7898c99 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00106.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00200.png b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_input_and_commitment/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00000.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00100.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00100.png new file mode 100644 index 0000000..8eb7eca Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00101.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00101.png new file mode 100644 index 0000000..94cbe16 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00102.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00102.png new file mode 100644 index 0000000..57f8edc Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00102.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00103.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00103.png new file mode 100644 index 0000000..adb48cb Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00103.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00104.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00104.png new file mode 100644 index 0000000..bac888b Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00104.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00105.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00105.png new file mode 100644 index 0000000..ff2c2a8 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00105.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00106.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00106.png new file mode 100644 index 0000000..9f6dc8d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00106.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00107.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00107.png new file mode 100644 index 0000000..8a490a4 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00107.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00108.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00108.png new file mode 100644 index 0000000..18123a5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00108.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00109.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00109.png new file mode 100644 index 0000000..615928e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00109.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00110.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00110.png new file mode 100644 index 0000000..214e45d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00110.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00111.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00111.png new file mode 100644 index 0000000..1da0b67 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00111.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00112.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00112.png new file mode 100644 index 0000000..43ae4fb Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00112.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00113.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00113.png new file mode 100644 index 0000000..06534a7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00113.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00114.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00114.png new file mode 100644 index 0000000..3cfd3b1 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00114.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00115.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00115.png new file mode 100644 index 0000000..93af868 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00115.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00116.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00116.png new file mode 100644 index 0000000..f4ec1f4 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00116.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00117.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00117.png new file mode 100644 index 0000000..3f4b57f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00117.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00118.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00118.png new file mode 100644 index 0000000..175dcbd Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00118.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00119.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00119.png new file mode 100644 index 0000000..11e1d3f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00119.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00120.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00120.png new file mode 100644 index 0000000..af149c9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00120.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00121.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00121.png new file mode 100644 index 0000000..8a6f6ed Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00121.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_large_output/00200.png b/tests/snapshots/nanox/test_sign_tx_with_large_output/00200.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_with_large_output/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00000.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00000.png new file mode 100644 index 0000000..640e079 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00100.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00100.png new file mode 100644 index 0000000..eaa64e5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00100.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00101.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00101.png new file mode 100644 index 0000000..351a884 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00101.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00200.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00200.png new file mode 100644 index 0000000..11e1d3f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00200.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_mint_tokens/00026.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00201.png similarity index 100% rename from tests/snapshots/nanox/test_sign_tx_mint_tokens/00026.png rename to tests/snapshots/nanox/test_sign_tx_without_outputs/00201.png diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00202.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00202.png new file mode 100644 index 0000000..567675f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00202.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_without_outputs/00300.png b/tests/snapshots/nanox/test_sign_tx_without_outputs/00300.png new file mode 100644 index 0000000..3a16119 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_without_outputs/00300.png differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00001.png b/tests/snapshots/stax/test_app_mainmenu/00001.png index 79a7cdf..10a8392 100644 Binary files a/tests/snapshots/stax/test_app_mainmenu/00001.png and b/tests/snapshots/stax/test_app_mainmenu/00001.png differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00002.png b/tests/snapshots/stax/test_app_mainmenu/00002.png deleted file mode 100644 index b0c222a..0000000 Binary files a/tests/snapshots/stax/test_app_mainmenu/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00003.png b/tests/snapshots/stax/test_app_mainmenu/00003.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_app_mainmenu/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/00003.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/00003.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_large_message/00000.png b/tests/snapshots/stax/test_sign_large_message/00000.png new file mode 100644 index 0000000..9beaf55 Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00000.png differ diff --git a/tests/snapshots/stax/test_sign_large_message/00001.png b/tests/snapshots/stax/test_sign_large_message/00001.png new file mode 100644 index 0000000..f94393b Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00001.png differ diff --git a/tests/snapshots/stax/test_sign_large_message/00002.png b/tests/snapshots/stax/test_sign_large_message/00002.png new file mode 100644 index 0000000..43a2b81 Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00002.png differ diff --git a/tests/snapshots/stax/test_sign_large_message/00003.png b/tests/snapshots/stax/test_sign_large_message/00003.png new file mode 100644 index 0000000..9645708 Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00003.png differ diff --git a/tests/snapshots/stax/test_sign_large_message/00004.png b/tests/snapshots/stax/test_sign_large_message/00004.png new file mode 100644 index 0000000..650a6f3 Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00004.png differ diff --git a/tests/snapshots/stax/test_sign_large_message/00005.png b/tests/snapshots/stax/test_sign_large_message/00005.png new file mode 100644 index 0000000..a08dbb1 Binary files /dev/null and b/tests/snapshots/stax/test_sign_large_message/00005.png differ diff --git a/tests/snapshots/stax/test_sign_message/00000.png b/tests/snapshots/stax/test_sign_message/00000.png index 5d5c468..c75b6df 100644 Binary files a/tests/snapshots/stax/test_sign_message/00000.png and b/tests/snapshots/stax/test_sign_message/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_pkh/00000.png b/tests/snapshots/stax/test_sign_message_pkh/00000.png index 5d5c468..c75b6df 100644 Binary files a/tests/snapshots/stax/test_sign_message_pkh/00000.png and b/tests/snapshots/stax/test_sign_message_pkh/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_refused/00000.png b/tests/snapshots/stax/test_sign_message_refused/00000.png index 5d5c468..c75b6df 100644 Binary files a/tests/snapshots/stax/test_sign_message_refused/00000.png and b/tests/snapshots/stax/test_sign_message_refused/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_refused/00005.png b/tests/snapshots/stax/test_sign_message_refused/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_message_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00001.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00001.png deleted file mode 100644 index 013b703..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00002.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00002.png deleted file mode 100644 index 269b12a..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00003.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00003.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00004.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00004.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00020.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00020.png deleted file mode 100644 index 72d8de9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00023.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_authority/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00010.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_authority/00010.png rename to tests/snapshots/stax/test_sign_tx_change_token_authority/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00011.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_authority/00011.png rename to tests/snapshots/stax/test_sign_tx_change_token_authority/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00200.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00200.png new file mode 100644 index 0000000..14a4dca Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_change_token_authority/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00021.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_authority/00021.png rename to tests/snapshots/stax/test_sign_tx_change_token_authority/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_authority/00022.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_authority/00022.png rename to tests/snapshots/stax/test_sign_tx_change_token_authority/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00004.png b/tests/snapshots/stax/test_sign_tx_change_token_authority/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_delegation/00004.png rename to tests/snapshots/stax/test_sign_tx_change_token_authority/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00001.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00001.png deleted file mode 100644 index 013b703..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00002.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00002.png deleted file mode 100644 index 0d66aad..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00003.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00003.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00004.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00004.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00020.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00020.png deleted file mode 100644 index 72d8de9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00023.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00010.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00010.png rename to tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00011.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00011.png rename to tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00200.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00200.png new file mode 100644 index 0000000..14a4dca Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00021.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00021.png rename to tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00022.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00022.png rename to tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00013.png b/tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_delegation/00013.png rename to tests/snapshots/stax/test_sign_tx_change_token_metadata_uri/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00001.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00001.png deleted file mode 100644 index d218625..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_delegation/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00002.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00002.png deleted file mode 100644 index c009444..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_delegation/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00003.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00003.png deleted file mode 100644 index 3343c26..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_delegation/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00005.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_delegation/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00010.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_delegation/00010.png rename to tests/snapshots/stax/test_sign_tx_create_delegation/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00011.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_delegation/00011.png rename to tests/snapshots/stax/test_sign_tx_create_delegation/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_create_delegation/00012.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00102.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_delegation/00012.png rename to tests/snapshots/stax/test_sign_tx_create_delegation/00102.png diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00004.png b/tests/snapshots/stax/test_sign_tx_create_delegation/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_stake_pool/00004.png rename to tests/snapshots/stax/test_sign_tx_create_delegation/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00001.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00001.png deleted file mode 100644 index 608c3d6..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00002.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00002.png deleted file mode 100644 index b1c1cd8..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00003.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00003.png deleted file mode 100644 index b91a1ee..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00005.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00010.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_stake_pool/00010.png rename to tests/snapshots/stax/test_sign_tx_create_stake_pool/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00011.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_stake_pool/00011.png rename to tests/snapshots/stax/test_sign_tx_create_stake_pool/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00012.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00102.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_stake_pool/00012.png rename to tests/snapshots/stax/test_sign_tx_create_stake_pool/00102.png diff --git a/tests/snapshots/stax/test_sign_tx_create_stake_pool/00013.png b/tests/snapshots/stax/test_sign_tx_create_stake_pool/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_create_stake_pool/00013.png rename to tests/snapshots/stax/test_sign_tx_create_stake_pool/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00000.png b/tests/snapshots/stax/test_sign_tx_delegate_staking/00000.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_delegation_staking/00000.png rename to tests/snapshots/stax/test_sign_tx_delegate_staking/00000.png diff --git a/tests/snapshots/stax/test_sign_tx_delegate_staking/00100.png b/tests/snapshots/stax/test_sign_tx_delegate_staking/00100.png new file mode 100644 index 0000000..ec8dd5b Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_delegate_staking/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00011.png b/tests/snapshots/stax/test_sign_tx_delegate_staking/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_delegation_staking/00011.png rename to tests/snapshots/stax/test_sign_tx_delegate_staking/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_delegate_staking/00102.png b/tests/snapshots/stax/test_sign_tx_delegate_staking/00102.png new file mode 100644 index 0000000..2bc14dc Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_delegate_staking/00102.png differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00003.png b/tests/snapshots/stax/test_sign_tx_delegate_staking/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_delegation_staking/00003.png rename to tests/snapshots/stax/test_sign_tx_delegate_staking/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00001.png b/tests/snapshots/stax/test_sign_tx_delegation_staking/00001.png deleted file mode 100644 index 35ed6fc..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_delegation_staking/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00002.png b/tests/snapshots/stax/test_sign_tx_delegation_staking/00002.png deleted file mode 100644 index c9c4a7d..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_delegation_staking/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00004.png b/tests/snapshots/stax/test_sign_tx_delegation_staking/00004.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_delegation_staking/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00010.png b/tests/snapshots/stax/test_sign_tx_delegation_staking/00010.png deleted file mode 100644 index 1a066d1..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_delegation_staking/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00012.png b/tests/snapshots/stax/test_sign_tx_delegation_staking/00012.png deleted file mode 100644 index 6b5de9f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_delegation_staking/00012.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00001.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00001.png deleted file mode 100644 index 013b703..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00002.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00002.png deleted file mode 100644 index d676523..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00003.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00003.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00004.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00004.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00020.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00020.png deleted file mode 100644 index 72d8de9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00023.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00010.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_freeze_tokens/00010.png rename to tests/snapshots/stax/test_sign_tx_freeze_tokens/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00011.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_freeze_tokens/00011.png rename to tests/snapshots/stax/test_sign_tx_freeze_tokens/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00200.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00200.png new file mode 100644 index 0000000..14a4dca Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00021.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_freeze_tokens/00021.png rename to tests/snapshots/stax/test_sign_tx_freeze_tokens/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_freeze_tokens/00022.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_freeze_tokens/00022.png rename to tests/snapshots/stax/test_sign_tx_freeze_tokens/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_delegation_staking/00013.png b/tests/snapshots/stax/test_sign_tx_freeze_tokens/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_delegation_staking/00013.png rename to tests/snapshots/stax/test_sign_tx_freeze_tokens/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00001.png b/tests/snapshots/stax/test_sign_tx_htlc/00001.png deleted file mode 100644 index 6620584..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_htlc/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00002.png b/tests/snapshots/stax/test_sign_tx_htlc/00002.png deleted file mode 100644 index bc6517b..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_htlc/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00003.png b/tests/snapshots/stax/test_sign_tx_htlc/00003.png deleted file mode 100644 index 4978a94..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_htlc/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00005.png b/tests/snapshots/stax/test_sign_tx_htlc/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_htlc/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00020.png b/tests/snapshots/stax/test_sign_tx_htlc/00020.png deleted file mode 100644 index f6c837f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_htlc/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00010.png b/tests/snapshots/stax/test_sign_tx_htlc/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00010.png rename to tests/snapshots/stax/test_sign_tx_htlc/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00011.png b/tests/snapshots/stax/test_sign_tx_htlc/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00011.png rename to tests/snapshots/stax/test_sign_tx_htlc/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00200.png b/tests/snapshots/stax/test_sign_tx_htlc/00200.png new file mode 100644 index 0000000..c1443b8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_htlc/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00021.png b/tests/snapshots/stax/test_sign_tx_htlc/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00021.png rename to tests/snapshots/stax/test_sign_tx_htlc/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00022.png b/tests/snapshots/stax/test_sign_tx_htlc/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00022.png rename to tests/snapshots/stax/test_sign_tx_htlc/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00004.png b/tests/snapshots/stax/test_sign_tx_htlc/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00004.png rename to tests/snapshots/stax/test_sign_tx_htlc/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00001.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00001.png deleted file mode 100644 index 3db0e08..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00002.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00002.png deleted file mode 100644 index c009444..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00003.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00003.png deleted file mode 100644 index 56b7625..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00005.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00010.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_fungible_token/00010.png rename to tests/snapshots/stax/test_sign_tx_issue_fungible_token/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00011.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_fungible_token/00011.png rename to tests/snapshots/stax/test_sign_tx_issue_fungible_token/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00012.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00102.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_fungible_token/00012.png rename to tests/snapshots/stax/test_sign_tx_issue_fungible_token/00102.png diff --git a/tests/snapshots/stax/test_sign_tx_htlc/00023.png b/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_htlc/00023.png rename to tests/snapshots/stax/test_sign_tx_issue_fungible_token/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00001.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00001.png deleted file mode 100644 index f230c4a..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_nft/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00002.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00002.png deleted file mode 100644 index 51f50f2..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_nft/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00003.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00003.png deleted file mode 100644 index f6bc246..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_nft/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00005.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_nft/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00010.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00010.png deleted file mode 100644 index 20c3f49..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_issue_nft/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00100.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00100.png new file mode 100644 index 0000000..f8545e4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_issue_nft/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00011.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_nft/00011.png rename to tests/snapshots/stax/test_sign_tx_issue_nft/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00012.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00102.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_nft/00012.png rename to tests/snapshots/stax/test_sign_tx_issue_nft/00102.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00004.png b/tests/snapshots/stax/test_sign_tx_issue_nft/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_fungible_token/00004.png rename to tests/snapshots/stax/test_sign_tx_issue_nft/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00001.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00001.png deleted file mode 100644 index fd9ba80..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00002.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00002.png deleted file mode 100644 index b1c1cd8..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00003.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00003.png deleted file mode 100644 index f541d00..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00005.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00005.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00010.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00010.png deleted file mode 100644 index 9f3c01a..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00011.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00011.png deleted file mode 100644 index 9f3c01a..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00011.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00020.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00020.png deleted file mode 100644 index 0a6eca3..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00022.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00022.png deleted file mode 100644 index 9794da4..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00022.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00100.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00100.png new file mode 100644 index 0000000..d535786 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00101.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00101.png new file mode 100644 index 0000000..d535786 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00200.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00200.png new file mode 100644 index 0000000..42cc985 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00021.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_lock_then_transfer/00021.png rename to tests/snapshots/stax/test_sign_tx_lock_then_transfer/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00202.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00202.png new file mode 100644 index 0000000..e4a5bc4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00202.png differ diff --git a/tests/snapshots/stax/test_sign_tx_issue_fungible_token/00013.png b/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_fungible_token/00013.png rename to tests/snapshots/stax/test_sign_tx_lock_then_transfer/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00000.png b/tests/snapshots/stax/test_sign_tx_long_tx/00000.png deleted file mode 100644 index 46a27b1..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00001.png b/tests/snapshots/stax/test_sign_tx_long_tx/00001.png deleted file mode 100644 index 71804d2..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00002.png b/tests/snapshots/stax/test_sign_tx_long_tx/00002.png deleted file mode 100644 index 19e831c..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00003.png b/tests/snapshots/stax/test_sign_tx_long_tx/00003.png deleted file mode 100644 index f5e027f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00004.png b/tests/snapshots/stax/test_sign_tx_long_tx/00004.png deleted file mode 100644 index 392165d..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_long_tx/00005.png b/tests/snapshots/stax/test_sign_tx_long_tx/00005.png deleted file mode 100644 index 52f987c..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_long_tx/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00001.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00001.png deleted file mode 100644 index 71d44cc..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00002.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00002.png deleted file mode 100644 index 835929b..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00003.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00003.png deleted file mode 100644 index 12f0520..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00004.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00004.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00005.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00005.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00010.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00010.png deleted file mode 100644 index 97f7cab..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00011.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00011.png deleted file mode 100644 index 97f7cab..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00011.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00020.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00020.png deleted file mode 100644 index 963a02f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00023.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_mint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00100.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00100.png new file mode 100644 index 0000000..ab5f855 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_mint_tokens/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00101.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00101.png new file mode 100644 index 0000000..ab5f855 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_mint_tokens/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00200.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00200.png new file mode 100644 index 0000000..0ae4a95 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_mint_tokens/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00021.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_mint_tokens/00021.png rename to tests/snapshots/stax/test_sign_tx_mint_tokens/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_mint_tokens/00022.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_mint_tokens/00022.png rename to tests/snapshots/stax/test_sign_tx_mint_tokens/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00004.png b/tests/snapshots/stax/test_sign_tx_mint_tokens/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_nft/00004.png rename to tests/snapshots/stax/test_sign_tx_mint_tokens/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00001.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00001.png deleted file mode 100644 index 545c8fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00002.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00002.png deleted file mode 100644 index 538cefb..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00003.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00003.png deleted file mode 100644 index 034fc05..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00004.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00004.png deleted file mode 100644 index 596f1b1..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00005.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00005.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00006.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00006.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00006.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00010.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00010.png deleted file mode 100644 index 22942eb..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00011.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00011.png deleted file mode 100644 index 22942eb..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00011.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00020.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00020.png deleted file mode 100644 index 2dbab71..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00021.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00021.png deleted file mode 100644 index 2dbab71..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00021.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00030.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00030.png deleted file mode 100644 index 963a02f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00030.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00033.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00033.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_conclude/00033.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00100.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00100.png new file mode 100644 index 0000000..5376024 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_conclude/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00101.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00101.png new file mode 100644 index 0000000..5376024 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_conclude/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00200.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00200.png new file mode 100644 index 0000000..87f9c29 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_conclude/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00201.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00201.png new file mode 100644 index 0000000..87f9c29 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_conclude/00201.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00300.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00300.png new file mode 100644 index 0000000..8da0054 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_conclude/00300.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00031.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00301.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_order_conclude/00031.png rename to tests/snapshots/stax/test_sign_tx_order_conclude/00301.png diff --git a/tests/snapshots/stax/test_sign_tx_order_conclude/00032.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00302.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_order_conclude/00032.png rename to tests/snapshots/stax/test_sign_tx_order_conclude/00302.png diff --git a/tests/snapshots/stax/test_sign_tx_issue_nft/00013.png b/tests/snapshots/stax/test_sign_tx_order_conclude/00400.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_issue_nft/00013.png rename to tests/snapshots/stax/test_sign_tx_order_conclude/00400.png diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00001.png b/tests/snapshots/stax/test_sign_tx_order_fill/00001.png deleted file mode 100644 index 6789ed4..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00002.png b/tests/snapshots/stax/test_sign_tx_order_fill/00002.png deleted file mode 100644 index 538cefb..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00003.png b/tests/snapshots/stax/test_sign_tx_order_fill/00003.png deleted file mode 100644 index 034fc05..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00004.png b/tests/snapshots/stax/test_sign_tx_order_fill/00004.png deleted file mode 100644 index 1b588b9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00005.png b/tests/snapshots/stax/test_sign_tx_order_fill/00005.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00006.png b/tests/snapshots/stax/test_sign_tx_order_fill/00006.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00006.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00010.png b/tests/snapshots/stax/test_sign_tx_order_fill/00010.png deleted file mode 100644 index 14b8012..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00011.png b/tests/snapshots/stax/test_sign_tx_order_fill/00011.png deleted file mode 100644 index 14b8012..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00011.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00020.png b/tests/snapshots/stax/test_sign_tx_order_fill/00020.png deleted file mode 100644 index f6c837f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00021.png b/tests/snapshots/stax/test_sign_tx_order_fill/00021.png deleted file mode 100644 index f6c837f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00021.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00030.png b/tests/snapshots/stax/test_sign_tx_order_fill/00030.png deleted file mode 100644 index 963a02f..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00030.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00033.png b/tests/snapshots/stax/test_sign_tx_order_fill/00033.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_order_fill/00033.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00100.png b/tests/snapshots/stax/test_sign_tx_order_fill/00100.png new file mode 100644 index 0000000..a617a80 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_fill/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00101.png b/tests/snapshots/stax/test_sign_tx_order_fill/00101.png new file mode 100644 index 0000000..a617a80 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_fill/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00200.png b/tests/snapshots/stax/test_sign_tx_order_fill/00200.png new file mode 100644 index 0000000..c1443b8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_fill/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00201.png b/tests/snapshots/stax/test_sign_tx_order_fill/00201.png new file mode 100644 index 0000000..c1443b8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_fill/00201.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00300.png b/tests/snapshots/stax/test_sign_tx_order_fill/00300.png new file mode 100644 index 0000000..b74dcaa Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_order_fill/00300.png differ diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00031.png b/tests/snapshots/stax/test_sign_tx_order_fill/00301.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_order_fill/00031.png rename to tests/snapshots/stax/test_sign_tx_order_fill/00301.png diff --git a/tests/snapshots/stax/test_sign_tx_order_fill/00032.png b/tests/snapshots/stax/test_sign_tx_order_fill/00302.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_order_fill/00032.png rename to tests/snapshots/stax/test_sign_tx_order_fill/00302.png diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00004.png b/tests/snapshots/stax/test_sign_tx_order_fill/00400.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_lock_then_transfer/00004.png rename to tests/snapshots/stax/test_sign_tx_order_fill/00400.png diff --git a/tests/snapshots/stax/test_sign_tx_refused/00000.png b/tests/snapshots/stax/test_sign_tx_refused/00000.png deleted file mode 100644 index 7601f58..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00000.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/00001.png b/tests/snapshots/stax/test_sign_tx_refused/00001.png deleted file mode 100644 index f2de498..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/00002.png b/tests/snapshots/stax/test_sign_tx_refused/00002.png deleted file mode 100644 index bb50c81..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/00003.png b/tests/snapshots/stax/test_sign_tx_refused/00003.png deleted file mode 100644 index abc9677..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/00004.png b/tests/snapshots/stax/test_sign_tx_refused/00004.png deleted file mode 100644 index 2b66970..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/00005.png b/tests/snapshots/stax/test_sign_tx_refused/00005.png deleted file mode 100644 index 52f987c..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_refused/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx/00000.png b/tests/snapshots/stax/test_sign_tx_short_tx/00000.png deleted file mode 100644 index 7601f58..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx/00000.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx/00001.png b/tests/snapshots/stax/test_sign_tx_short_tx/00001.png deleted file mode 100644 index 4168d43..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx/00002.png b/tests/snapshots/stax/test_sign_tx_short_tx/00002.png deleted file mode 100644 index bb50c81..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx/00003.png b/tests/snapshots/stax/test_sign_tx_short_tx/00003.png deleted file mode 100644 index 392165d..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx/00004.png b/tests/snapshots/stax/test_sign_tx_short_tx/00004.png deleted file mode 100644 index 52f987c..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00000.png b/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00000.png deleted file mode 100644 index 7601f58..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00000.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00001.png b/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00001.png deleted file mode 100644 index d658c95..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00002.png b/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00002.png deleted file mode 100644 index bb50c81..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00003.png b/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00003.png deleted file mode 100644 index 392165d..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00004.png b/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00004.png deleted file mode 100644 index 52f987c..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_short_tx_no_memo/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00001.png b/tests/snapshots/stax/test_sign_tx_transfer/00001.png deleted file mode 100644 index edec633..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_transfer/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00002.png b/tests/snapshots/stax/test_sign_tx_transfer/00002.png deleted file mode 100644 index ea259ca..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_transfer/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00004.png b/tests/snapshots/stax/test_sign_tx_transfer/00004.png deleted file mode 100644 index d755792..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_transfer/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00010.png b/tests/snapshots/stax/test_sign_tx_transfer/00010.png deleted file mode 100644 index 72f49ca..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_transfer/00010.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00100.png b/tests/snapshots/stax/test_sign_tx_transfer/00100.png new file mode 100644 index 0000000..3dfb266 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_transfer/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00011.png b/tests/snapshots/stax/test_sign_tx_transfer/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_transfer/00011.png rename to tests/snapshots/stax/test_sign_tx_transfer/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00012.png b/tests/snapshots/stax/test_sign_tx_transfer/00102.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_transfer/00012.png rename to tests/snapshots/stax/test_sign_tx_transfer/00102.png diff --git a/tests/snapshots/stax/test_sign_tx_lock_then_transfer/00023.png b/tests/snapshots/stax/test_sign_tx_transfer/00200.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_lock_then_transfer/00023.png rename to tests/snapshots/stax/test_sign_tx_transfer/00200.png diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00001.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00001.png deleted file mode 100644 index 013b703..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00002.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00002.png deleted file mode 100644 index 3dc1f34..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00003.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00003.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00004.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00004.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00020.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00020.png deleted file mode 100644 index 72d8de9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00023.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00010.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00010.png rename to tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00011.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00011.png rename to tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00200.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00200.png new file mode 100644 index 0000000..14a4dca Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00021.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00201.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00021.png rename to tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00201.png diff --git a/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00022.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00022.png rename to tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00003.png b/tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_transfer/00003.png rename to tests/snapshots/stax/test_sign_tx_unfreeze_tokens/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00001.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00001.png deleted file mode 100644 index b33c474..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00001.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00002.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00002.png deleted file mode 100644 index d71d1f4..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00002.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00003.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00003.png deleted file mode 100644 index cb9e0d0..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00003.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00004.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00004.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00004.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00005.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00005.png deleted file mode 100644 index 9e274be..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00005.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00020.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00020.png deleted file mode 100644 index 72d8de9..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00020.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00021.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00021.png deleted file mode 100644 index da9a826..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00021.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00023.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00023.png deleted file mode 100644 index a5379fa..0000000 Binary files a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00023.png and /dev/null differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00010.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00100.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unmint_tokens/00010.png rename to tests/snapshots/stax/test_sign_tx_unmint_tokens/00100.png diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00011.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00101.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unmint_tokens/00011.png rename to tests/snapshots/stax/test_sign_tx_unmint_tokens/00101.png diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00200.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00200.png new file mode 100644 index 0000000..14a4dca Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00201.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00201.png new file mode 100644 index 0000000..595823c Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00201.png differ diff --git a/tests/snapshots/stax/test_sign_tx_unmint_tokens/00022.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00202.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_unmint_tokens/00022.png rename to tests/snapshots/stax/test_sign_tx_unmint_tokens/00202.png diff --git a/tests/snapshots/stax/test_sign_tx_transfer/00013.png b/tests/snapshots/stax/test_sign_tx_unmint_tokens/00300.png similarity index 100% rename from tests/snapshots/stax/test_sign_tx_transfer/00013.png rename to tests/snapshots/stax/test_sign_tx_unmint_tokens/00300.png diff --git a/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00000.png b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00000.png new file mode 100644 index 0000000..a46449f Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00100.png b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00100.png new file mode 100644 index 0000000..93dbdfd Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00101.png b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00101.png new file mode 100644 index 0000000..38c3471 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00102.png b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00102.png new file mode 100644 index 0000000..fad9bf9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00102.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00200.png b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00200.png new file mode 100644 index 0000000..ceda6a8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_input_and_commitment/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_output/00000.png b/tests/snapshots/stax/test_sign_tx_with_large_output/00000.png new file mode 100644 index 0000000..a46449f Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_output/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_output/00100.png b/tests/snapshots/stax/test_sign_tx_with_large_output/00100.png new file mode 100644 index 0000000..f8545e4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_output/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_output/00101.png b/tests/snapshots/stax/test_sign_tx_with_large_output/00101.png new file mode 100644 index 0000000..82af017 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_output/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_output/00102.png b/tests/snapshots/stax/test_sign_tx_with_large_output/00102.png new file mode 100644 index 0000000..63885c4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_output/00102.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_large_output/00200.png b/tests/snapshots/stax/test_sign_tx_with_large_output/00200.png new file mode 100644 index 0000000..ceda6a8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_with_large_output/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_without_outputs/00000.png b/tests/snapshots/stax/test_sign_tx_without_outputs/00000.png new file mode 100644 index 0000000..a46449f Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_without_outputs/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_without_outputs/00100.png b/tests/snapshots/stax/test_sign_tx_without_outputs/00100.png new file mode 100644 index 0000000..0923fc4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_without_outputs/00100.png differ diff --git a/tests/snapshots/stax/test_sign_tx_without_outputs/00101.png b/tests/snapshots/stax/test_sign_tx_without_outputs/00101.png new file mode 100644 index 0000000..0923fc4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_without_outputs/00101.png differ diff --git a/tests/snapshots/stax/test_sign_tx_without_outputs/00200.png b/tests/snapshots/stax/test_sign_tx_without_outputs/00200.png new file mode 100644 index 0000000..c40ddea Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_without_outputs/00200.png differ diff --git a/tests/snapshots/stax/test_sign_tx_without_outputs/00300.png b/tests/snapshots/stax/test_sign_tx_without_outputs/00300.png new file mode 100644 index 0000000..ceda6a8 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_without_outputs/00300.png differ diff --git a/tests/test_app_mainmenu.py b/tests/test_app_mainmenu.py index a55bdc3..dfb9e71 100644 --- a/tests/test_app_mainmenu.py +++ b/tests/test_app_mainmenu.py @@ -7,13 +7,14 @@ def test_app_mainmenu(device, navigator, test_name): # Navigate in the main menu if device.is_nano: - instructions = [ - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK - ] + instructions = [NavInsID.RIGHT_CLICK, NavInsID.RIGHT_CLICK] else: instructions = [ NavInsID.USE_CASE_HOME_SETTINGS, ] - navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, test_name, instructions, - screen_change_before_first_instruction=False) + navigator.navigate_and_compare( + ROOT_SCREENSHOT_PATH, + test_name, + instructions, + screen_change_before_first_instruction=False, + ) diff --git a/tests/test_error_cmd.py b/tests/test_error_cmd.py index f9d10a5..88c6b2b 100644 --- a/tests/test_error_cmd.py +++ b/tests/test_error_cmd.py @@ -1,13 +1,20 @@ import pytest -import scalecodec # type: ignore from ragger.error import ExceptionRAPDU from application_client import MAINNET -from application_client.mintlayer_command_sender import (CLA, GetAppAndVersionP1, SignTxP1, P2, Errors, - InsType) +from application_client.mintlayer_command_sender import ( + CLA, + GetAppAndVersionP1, + SignTxP1, + P2, + Errors, + InsType, +) +from application_client.mintlayer_utils import ( + sign_tx_start_req_obj, + sign_tx_next_req_obj, +) -tx_metadata_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("TxMetadataReq") -sign_tx_req_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("SignTxReq") # Ensure the app returns an error when a bad CLA is used def test_bad_cla(backend): @@ -33,13 +40,19 @@ def test_wrong_p1p2(backend): assert e.value.status == Errors.SW_WRONG_P1P2 backend.exchange( - cla=CLA, ins=InsType.GET_PUBLIC_KEY, p1=GetAppAndVersionP1.P1_START, p2=P2.P2_MORE - ) - + cla=CLA, + ins=InsType.GET_PUBLIC_KEY, + p1=GetAppAndVersionP1.P1_START, + p2=P2.P2_MORE, + ) + # Wrong P1 after sending MORE with pytest.raises(ExceptionRAPDU) as e: backend.exchange( - cla=CLA, ins=InsType.GET_PUBLIC_KEY, p1=GetAppAndVersionP1.P1_START + 1, p2=P2.P2_MORE + cla=CLA, + ins=InsType.GET_PUBLIC_KEY, + p1=GetAppAndVersionP1.P1_START + 1, + p2=P2.P2_MORE, ) assert e.value.status == Errors.SW_WRONG_P1P2 @@ -72,15 +85,12 @@ def test_sign_tx_invalid_coin(backend, scenario_navigator, device, navigator): invalid_coin = 255 num_inputs = 1 num_outputs = 1 - metadata = tx_metadata_obj.encode( + start_req = sign_tx_start_req_obj.encode( { "coin": invalid_coin, - "version": { - "V1": { - "num_inputs": num_inputs, - "num_outputs": num_outputs, - }, - }, + "version": 0, + "num_inputs": num_inputs, + "num_outputs": num_outputs, } ).data @@ -90,7 +100,7 @@ def test_sign_tx_invalid_coin(backend, scenario_navigator, device, navigator): ins=InsType.SIGN_TX, p1=SignTxP1.P1_START, p2=P2.P2_LAST, - data=bytes(metadata), + data=bytes(start_req), ) assert e.value.status == Errors.SW_DESERIALIZE_FAIL @@ -98,20 +108,17 @@ def test_sign_tx_invalid_coin(backend, scenario_navigator, device, navigator): def test_sign_tx_invalid_context(backend, scenario_navigator, device, navigator): """ - After metadata try to pass an output instead of the input + After the start request try to pass an output instead of the input expect an error for wrong context """ num_inputs = 2 num_outputs = 2 - metadata = tx_metadata_obj.encode( + start_req = sign_tx_start_req_obj.encode( { "coin": MAINNET, - "version": { - "V1": { - "num_inputs": num_inputs, - "num_outputs": num_outputs, - }, - }, + "version": 0, + "num_inputs": num_inputs, + "num_outputs": num_outputs, } ).data @@ -120,7 +127,7 @@ def test_sign_tx_invalid_context(backend, scenario_navigator, device, navigator) ins=InsType.SIGN_TX, p1=SignTxP1.P1_START, p2=P2.P2_LAST, - data=bytes(metadata), + data=bytes(start_req), ) assert res.status == 0x9000 @@ -131,15 +138,19 @@ def test_sign_tx_invalid_context(backend, scenario_navigator, device, navigator) ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_LAST, - data=sign_tx_req_obj.encode( + data=sign_tx_next_req_obj.encode( { - "Output": { - "out": { + "ProcessOutput": { + "output": { "Transfer": [ {"Coin": 10}, { "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + "key": { + "Secp256k1Schnorr": { + "pubkey_data": bytes([0] * 33) + } + } } }, ], @@ -154,15 +165,12 @@ def test_sign_tx_invalid_context(backend, scenario_navigator, device, navigator) def test_sign_tx_invalid_input(backend, scenario_navigator, device, navigator): num_inputs = 2 num_outputs = 2 - metadata = tx_metadata_obj.encode( + start_req = sign_tx_start_req_obj.encode( { "coin": MAINNET, - "version": { - "V1": { - "num_inputs": num_inputs, - "num_outputs": num_outputs, - }, - }, + "version": 0, + "num_inputs": num_inputs, + "num_outputs": num_outputs, } ).data @@ -171,7 +179,7 @@ def test_sign_tx_invalid_input(backend, scenario_navigator, device, navigator): ins=InsType.SIGN_TX, p1=SignTxP1.P1_START, p2=P2.P2_LAST, - data=bytes(metadata), + data=bytes(start_req), ) print("res, ", res.status) @@ -192,15 +200,12 @@ def test_sign_tx_invalid_input(backend, scenario_navigator, device, navigator): def test_sign_tx_too_large_data(backend, scenario_navigator, device, navigator): num_inputs = 2 num_outputs = 2 - metadata = tx_metadata_obj.encode( + start_req = sign_tx_start_req_obj.encode( { "coin": MAINNET, - "version": { - "V1": { - "num_inputs": num_inputs, - "num_outputs": num_outputs, - }, - }, + "version": 0, + "num_inputs": num_inputs, + "num_outputs": num_outputs, } ).data @@ -209,19 +214,19 @@ def test_sign_tx_too_large_data(backend, scenario_navigator, device, navigator): ins=InsType.SIGN_TX, p1=SignTxP1.P1_START, p2=P2.P2_LAST, - data=bytes(metadata), + data=bytes(start_req), ) assert res.status == 0x9000 with pytest.raises(ExceptionRAPDU) as e: - for _ in range(100): + for _ in range(1000): res = backend.exchange( cla=CLA, ins=InsType.SIGN_TX, p1=SignTxP1.P1_NEXT, p2=P2.P2_MORE, - data=b"big_input_data", + data=b"input_data", ) assert e.value.status == Errors.SW_MAX_BUFFER_LEN_EXCEEDED diff --git a/tests/test_name_version.py b/tests/test_name_version.py index f822470..f326ff7 100644 --- a/tests/test_name_version.py +++ b/tests/test_name_version.py @@ -1,6 +1,7 @@ from application_client.mintlayer_command_sender import MintlayerCommandSender -from application_client.mintlayer_response_unpacker import \ - unpack_get_app_and_version_response +from application_client.mintlayer_response_unpacker import ( + unpack_get_app_and_version_response, +) # Test a specific APDU asking BOLOS (and not the app) the name and version of the current app @@ -13,4 +14,4 @@ def test_get_app_and_version(backend, backend_name): app_name, version = unpack_get_app_and_version_response(response.data) print(app_name, version) assert app_name == "Mintlayer" - assert version == "0.1.0" + assert version == "1.0.0" diff --git a/tests/test_pubkey_cmd.py b/tests/test_pubkey_cmd.py index 377aab8..8f3ef23 100644 --- a/tests/test_pubkey_cmd.py +++ b/tests/test_pubkey_cmd.py @@ -3,10 +3,10 @@ from ragger.error import ExceptionRAPDU from application_client import MAINNET, TESTNET -from application_client.mintlayer_command_sender import ( - Errors, MintlayerCommandSender) -from application_client.mintlayer_response_unpacker import \ - unpack_get_public_key_response +from application_client.mintlayer_command_sender import Errors, MintlayerCommandSender +from application_client.mintlayer_response_unpacker import ( + unpack_get_public_key_response, +) MNEMONIC = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" diff --git a/tests/test_sign_cmd.py b/tests/test_sign_cmd.py deleted file mode 100644 index 5bf93c0..0000000 --- a/tests/test_sign_cmd.py +++ /dev/null @@ -1,1650 +0,0 @@ -import pytest -import scalecodec -from ragger.navigator import NavIns, NavInsID - -from application_client import MAINNET -from application_client.mintlayer_command_sender import ( - MintlayerCommandSender, - sign_tx_review, - ReviewTransaction, -) -from application_client.mintlayer_response_unpacker import unpack_get_public_key_response -from application_client.mintlayer_transaction import Transaction - -sign_tx_req_obj = scalecodec.base.RuntimeConfiguration().create_scale_object("SignTxReq") - -TX_RESPONSE_SIZE = 71 - - -def test_sign_tx_transfer(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - # The path used for this entire test - path: str = "m/44'/19788'/0'/0/0" - - # First we need to get the public key of the device in order to build the transaction - rapdu = client.get_public_key(coin=MAINNET, path=path) - _, public_key, _, _ = unpack_get_public_key_response(rapdu.data) - - print("pk", len(public_key)) - - h = 1 << 31 - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - } - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} - } - }, - ], - } - } - } - ).data - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\stransfer" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_lock_then_transfer(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - # The path used for this entire test - path: str = "m/44'/19788'/0'/0/0" - - h = 1 << 31 - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Account": { - "nonce": 1, - "account": {"Delegation": [[0] * 32, 11]}, - } - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "LockThenTransfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} - } - }, - {"UntilHeight": 10}, - ], - } - } - } - ).data - - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\swithdrawal" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_create_delegation(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - h = 1 << 31 - - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "CreateDelegationId": [ - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} - } - }, - [0] * 32, - ], - } - } - } - ).data - - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\screate" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_delegation_staking(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - h = 1 << 31 - - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "DelegateStaking": [5, [0] * 32], - } - } - } - ).data - - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\sstake" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_create_stake_pool(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - h = 1 << 31 - - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 40001}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "CreateStakePool": [ - [0] * 32, - { - "value": 40000, - "staker": { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - "vrf_public_key": {"key": {"Schnorrkel": {"key": bytes([0] * 32)}}}, - "decommission_key": { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - "margin_ratio_per_thousand": 10, - "cost_per_block": 5, - }, - ], - } - } - } - ).data - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\screate\sstake" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_issue_fungible_token(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - h = 1 << 31 - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 10}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "IssueFungibleToken": { - "V1": { - "token_ticker": b"MYTKN", - "number_of_decimals": 8, - "metadata_uri": b"https://my.token.uri", - "total_supply": {"Fixed": 1000000000}, - "authority": { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - "is_freezable": {"Yes": None}, - } - }, - } - } - } - ).data - - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\screate\stoken" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_issue_nft(backend, scenario_navigator, device, navigator): - # Use the app interface instead of raw interface - client = MintlayerCommandSender(backend) - h = 1 << 31 - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 2000}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} - } - } - }, - ], - } - } - inp = sign_tx_req_obj.encode( - { - "Input": - { - "addresses": [ - {"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None} - ], - "inp": { - "Utxo": [ - { - "id": {"Transaction": "0x{}".format(bytes([0] * 32).hex())}, - "index": 1, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - # This is the new output for issuing an NFT. - # The structure is (TokenId, NftIssuance, Destination) - output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "IssueNft": [ - bytes([0] * 32), - { - "V0": { - "metadata": { - "creator": { - "public_key": { - "key": { - "Secp256k1Schnorr": { - "pubkey_data": bytes([0] * 33) - } - } - } - }, - "name": b"MyAwesomeNFT", - "description": b"FirstNFT", - "ticker": b"MNFT1", - "icon_uri": b"https://my.nft/icon.png", - "additional_metadata_uri": b"https://my.nft/meta.json", - "media_uri": b"https://my.nft/media.jpg", - "media_hash": bytes([0] * 32), - } - } - }, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} - } - }, - ], - } - } - } - ).data - - # Create the transaction that will be sent to the device for signing - transaction = Transaction( - coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\screate\sNFT" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_mint_tokens(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input. - 2. An AccountCommand input to mint new tokens. - And one output to transfer the newly minted tokens. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The utxo (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info - } - ).data - - # This is the AccountCommand to mint 1000 units of a new token - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - { - "MintTokens": [ - f"0x{bytes([0]*32).hex()}", # TokenId - 1000, # Amount to mint - ] - }, - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - mint_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"TokenV1": [f"0x{bytes([0]*32).hex()}", 1000]}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, acc_inp_commitment], - outputs=[mint_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\smint\stokens" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_unmint_tokens(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay tx fees. - 2. An AccountCommand input to unmint new tokens. - 3. A standard UTXO input with tokens to unmint - And one output to transfer the newly minted tokens. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional data (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - additional_info2 = { - "Utxo": { - "Transfer": [ - {"TokenV1": [f"0x{bytes([0]*32).hex()}", 1000]}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - utxo_input2 = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 2, - }, - additional_info2, - ] - }, - } - } - ).data - - inp_commitment2 = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info2, - } - ).data - - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - { - "UnmintTokens": f"0x{bytes([0]*32).hex()}", # TokenId - }, - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 99}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input, utxo_input2], - input_commitments=[inp_commitment, acc_inp_commitment, inp_commitment2], - outputs=[change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\sunmint\stokens" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_freeze_tokens(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An AccountCommand input to freeze the tokens. - And one output to transfer the change coins. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional info (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - # This is the AccountCommand to mint 1000 units of a new token - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - {"FreezeToken": [f"0x{bytes([0]*32).hex()}", {"No": None}]}, # TokenId - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 99}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, acc_inp_commitment], - outputs=[change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\sfreeze\stokens" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_unfreeze_tokens(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An AccountCommand input to unfreeze the tokens. - And one output to transfer the change coins. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional data (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - }).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - # This is the AccountCommand to mint 1000 units of a new token - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - { - "UnfreezeToken": f"0x{bytes([0]*32).hex()}", # TokenId - }, - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 99}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, acc_inp_commitment], - outputs=[change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\sunfreeze" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_change_token_authority(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An AccountCommand input to change the token's authority. - And one output to transfer the change coins. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional data (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - }).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - # This is the AccountCommand to mint 1000 units of a new token - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - { - "ChangeTokenAuthority": [ - f"0x{bytes([0]*32).hex()}", # TokenId - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ] - }, - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 99}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, acc_inp_commitment], - outputs=[change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\schange\stoken" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_change_token_metadata_uri( - backend, scenario_navigator, device, navigator -): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An AccountCommand input to change the token's metadata uri. - And one output to transfer the change coins. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional info (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - # This is the AccountCommand to mint 1000 units of a new token - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "AccountCommand": [ - 1, # AccountNonce - { - "ChangeTokenMetadataUri": [ - f"0x{bytes([0]*32).hex()}", # TokenId - "uri.com".encode(), - ] - }, - ] - }, - } - } - ).data - - acc_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": {"None": None} - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 99}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, acc_inp_commitment], - outputs=[change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\schange\stoken" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_order_fill(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An AccountCommand input to fill an order. - 3. A standard UTXO input to be used for the fill. - And one output to transfer the change coins. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additionl info (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - fill_amount = 10 - fill_ask = 100 - fill_give = 1000 - - additional_order_info = { - "initially_asked": {"Coin": fill_ask}, - "initially_given": {"TokenV1": [f"0x{bytes([0]*32).hex()}", fill_give]}, - "ask_balance": 0, - "give_balance": 0, - } - # This is the OrderAccountCommand to fill 10 units - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "OrderAccountCommand": [ - { - "FillOrder": [ - f"0x{bytes([0]*32).hex()}", # OrderId - fill_amount, - ] - }, - additional_order_info, - ] - }, - } - } - ).data - - fill_order_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": { - "FillOrderAccountCommand": [ - additional_order_info["initially_asked"], - additional_order_info["initially_given"], - ] - }, - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 100 - 1 - fill_amount}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - fill_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - { - "TokenV1": [ - f"0x{bytes([0]*32).hex()}", - fill_amount * fill_give // fill_ask, - ] - }, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, fill_order_inp_commitment], - outputs=[change_output, fill_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\sfill\sorder" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_order_conclude(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with two inputs: - 1. A standard UTXO input to pay for tx fees. - 2. An OrderAccountCommand input to conclude an order. - And one output to transfer the change coins + ask balance and another output for the give balance. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional_data (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - initial_ask = 100 - initial_give = 1000 - ask_balance = 10 - give_balance = 900 - - additional_order_info = { - "initially_asked": {"Coin": initial_ask}, - "initially_given": {"TokenV1": [f"0x{bytes([0]*32).hex()}", initial_give]}, - "ask_balance": ask_balance, - "give_balance": give_balance, - } - - # This is the OrderAccountCommand to fill 10 units - account_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "OrderAccountCommand": [ - { - "ConcludeOrder": f"0x{bytes([0]*32).hex()}", # OrderId - }, - additional_order_info, - ] - }, - } - } - ).data - - conclude_order_inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": { - "ConcludeOrderAccountCommand": [ - additional_order_info["initially_asked"], - additional_order_info["initially_given"], - additional_order_info["ask_balance"], - additional_order_info["give_balance"] - ] - }, - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 100 - 1 + ask_balance}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - conclude_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"TokenV1": [f"0x{bytes([0]*32).hex()}", give_balance]}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input, account_input], - input_commitments=[inp_commitment, conclude_order_inp_commitment], - outputs=[change_output, conclude_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=True, - review_custom_screen_text=r"Sign\sconclude\sorder" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) - - -def test_sign_tx_htlc(backend, scenario_navigator, device, navigator): - """ - Test signing a transaction with one input: - 1. The standard UTXO input to pay for tx fees. - And one output to transfer the change coins and the HTLC output. - """ - client = MintlayerCommandSender(backend) - h = 1 << 31 - bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] - - # The additional info (the previous TxOutput that this UTXO input spends) - # This represents an output of 100 coins owned by our key - additional_info = { - "Utxo": { - "Transfer": [ - {"Coin": 100}, - { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - ], - } - } - utxo_input = sign_tx_req_obj.encode( - { - "Input": { - "addresses": [{"path": bip44_path, "multisig_idx": None}], - "inp": { - "Utxo": [ - { - "id": {"Transaction": f"0x{bytes([1]*32).hex()}"}, - "index": 0, - }, - additional_info, - ] - }, - } - } - ).data - - inp_commitment = sign_tx_req_obj.encode( - { - "InputCommitment": additional_info, - } - ).data - - change_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Transfer": [ - {"Coin": 89}, - { - "PublicKey": { - "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} - } - }, - ], - } - } - } - ).data - - htlc_output = sign_tx_req_obj.encode( - { - "Output": { - "out": { - "Htlc": [ - {"Coin": 10}, - { - "secret_hash": [0] * 20, - "spend_key": { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} - } - } - }, - "refund_timelock": {"UntilHeight": 100}, - "refund_key": { - "PublicKey": { - "key": { - "Secp256k1Schnorr": {"pubkey_data": bytes([3] * 33)} - } - } - }, - }, - ], - } - } - } - ).data - - transaction = Transaction( - coin=MAINNET, - inputs=[utxo_input], - input_commitments=[inp_commitment], - outputs=[htlc_output, change_output], - ) - - review_tx = ReviewTransaction( - transaction=transaction, - has_command_input=False, - review_custom_screen_text=r"Sign\screate\sHTLC" - ) - sign_tx_review(client, device, navigator, scenario_navigator, review_tx) diff --git a/tests/test_sign_message.py b/tests/test_sign_message.py index 16d8406..b7b7dd0 100644 --- a/tests/test_sign_message.py +++ b/tests/test_sign_message.py @@ -2,10 +2,13 @@ from ragger.error import ExceptionRAPDU from application_client import MAINNET -from application_client.mintlayer_command_sender import ( - Errors, MintlayerCommandSender) +from application_client.mintlayer_command_sender import Errors, MintlayerCommandSender from application_client.mintlayer_response_unpacker import ( unpack_sign_message_response, + unpack_get_public_key_response, +) +from application_client.mintlayer_utils import ( + verify_message_signature, ) @@ -13,22 +16,54 @@ def test_sign_message(backend, scenario_navigator): path = "m/44'/19788'/0'/0/0" message = b"Hello" + coin = MAINNET client = MintlayerCommandSender(backend) - with client.sign_message(coin=MAINNET, addr_type=0, path=path, message=message): + + pubkey = get_pub_key(client, coin=coin, path=path) + + with client.sign_message(coin=coin, addr_type=0, path=path, message=message): + scenario_navigator.review_approve() + + sig = unpack_sign_message_response(client.get_async_response().data) + + sig_valid = verify_message_signature(message, pubkey, sig) + assert sig_valid, "Signature verification failed" + + +# Same as test_sign_message, but the message is large enough to require chunking +def test_sign_large_message(backend, scenario_navigator): + path = "m/44'/19788'/0'/0/0" + message = b"Hello" * 100 + coin = MAINNET + client = MintlayerCommandSender(backend) + + pubkey = get_pub_key(client, coin=coin, path=path) + + with client.sign_message(coin=coin, addr_type=0, path=path, message=message): scenario_navigator.review_approve() sig = unpack_sign_message_response(client.get_async_response().data) assert len(sig) == 64 + sig_valid = verify_message_signature(message, pubkey, sig) + assert sig_valid, "Signature verification failed" + + def test_sign_message_pkh(backend, scenario_navigator): path = "m/44'/19788'/0'/0/0" message = b"Hello" + coin = MAINNET client = MintlayerCommandSender(backend) - with client.sign_message(coin=MAINNET, addr_type=1, path=path, message=message): + + pubkey = get_pub_key(client, coin=coin, path=path) + + with client.sign_message(coin=coin, addr_type=1, path=path, message=message): scenario_navigator.review_approve() sig = unpack_sign_message_response(client.get_async_response().data) - assert len(sig) == 64 + + sig_valid = verify_message_signature(message, pubkey, sig) + assert sig_valid, "Signature verification failed" # Message signing refused test @@ -38,11 +73,18 @@ def test_sign_message_refused(backend, scenario_navigator): client = MintlayerCommandSender(backend) path: str = "m/44'/19788'/0'/0/0" message: bytes = b"Hello" + coin = MAINNET with pytest.raises(ExceptionRAPDU) as e: - with client.sign_message(coin=MAINNET, addr_type=0, path=path, message=message): + with client.sign_message(coin=coin, addr_type=0, path=path, message=message): scenario_navigator.review_reject() # Assert that we have received a refusal assert e.value.status == Errors.SW_DENY assert len(e.value.data) == 0 + + +def get_pub_key(client: MintlayerCommandSender, coin: int, path: str) -> bytes: + rapdu = client.get_public_key(coin, path) + _, pubkey, _, _ = unpack_get_public_key_response(rapdu.data) + return pubkey diff --git a/tests/test_sign_tx.py b/tests/test_sign_tx.py new file mode 100644 index 0000000..029ba00 --- /dev/null +++ b/tests/test_sign_tx.py @@ -0,0 +1,1591 @@ +from application_client import MAINNET +from application_client.mintlayer_command_sender import ( + MintlayerCommandSender, + sign_tx_review, + ReviewTransaction, +) +from application_client.mintlayer_response_unpacker import ( + unpack_get_public_key_response, +) +from application_client.mintlayer_utils import Transaction, sign_tx_next_req_obj + +# TODO: implement missing tests: +# * CreateOrder, DataDeposit, Burn outputs; +# * pool decommissioning; +# * LockTokenSupply, FreezeOrder commands; +# * maybe something else. +# See https://github.com/mintlayer/mintlayer-ledger-app/issues/19. + + +def test_sign_tx_transfer(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + # The path used for this entire test + path: str = "m/44'/19788'/0'/0/0" + + # First we need to get the public key of the device in order to build the transaction + rapdu = client.get_public_key(coin=MAINNET, path=path) + _, public_key, _, _ = unpack_get_public_key_response(rapdu.data) + + print("pk", len(public_key)) + + h = 1 << 31 + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "Transfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\stransfer", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_lock_then_transfer(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + # The path used for this entire test + path: str = "m/44'/19788'/0'/0/0" + + h = 1 << 31 + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Account": { + "nonce": 1, + "spending": {"DelegationBalance": [[0] * 32, 11]}, + } + }, + } + + inp_commitment = {"commitment": {"None": None}} + + output = { + "output": { + "LockThenTransfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + {"UntilHeight": 10}, + ], + } + } + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sdelegation", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_create_delegation(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "CreateDelegationId": [ + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + [0] * 32, + ], + } + } + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_delegate_staking(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "DelegateStaking": [5, [0] * 32], + } + } + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\sdelegate", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_create_stake_pool(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 40001}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "CreateStakePool": [ + [0] * 32, + { + "pledge": 40000, + "staker": { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} + } + } + }, + "vrf_public_key": {"key": {"Schnorrkel": {"key": bytes([0] * 32)}}}, + "decommission_key": { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} + } + } + }, + "margin_ratio_per_thousand": 10, + "cost_per_block": 5, + }, + ], + } + } + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate\sstake", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_issue_fungible_token(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 10}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "IssueFungibleToken": { + "V1": { + "token_ticker": b"MYTKN", + "number_of_decimals": 8, + "metadata_uri": b"https://my.token.uri", + "total_supply": {"Fixed": 1000000000}, + "authority": { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)} + } + } + }, + "is_freezable": {"Yes": None}, + } + }, + } + } + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate\stoken", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_issue_nft(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 2000}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + # This is the new output for issuing an NFT. + # The structure is (TokenId, NftIssuance, Destination) + output = { + "output": { + "IssueNft": [ + bytes([0] * 32), + { + "V0": { + "metadata": { + "creator": { + "public_key": { + "key": { + "Secp256k1Schnorr": { + "pubkey_data": bytes([0] * 33) + } + } + } + }, + "name": b"MyAwesomeNFT", + "description": b"FirstNFT", + "ticker": b"MNFT1", + "icon_uri": b"https://my.nft/icon.png", + "additional_metadata_uri": b"https://my.nft/meta.json", + "media_uri": b"https://my.nft/media.jpg", + "media_hash": bytes([0] * 32), + } + } + }, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate\sNFT", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_mint_tokens(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input. + 2. An AccountCommand input to mint new tokens. + And one output to transfer the newly minted tokens. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The utxo (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + { + "MintTokens": [ + token_id, + 1000, # Amount to mint + ] + }, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + mint_output = { + "output": { + "Transfer": [ + {"TokenV1": [token_id, 1000]}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[mint_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\smint\stokens", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_unmint_tokens(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay tx fees. + 2. An AccountCommand input to unmint new tokens. + 3. A standard UTXO input with tokens to unmint + And one output to transfer the newly minted tokens. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional data (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + additional_info2 = { + "Utxo": { + "Transfer": [ + {"TokenV1": [bytes([0] * 32), 1000]}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + utxo_input2 = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 2, + }, + additional_info2, + ] + }, + } + + inp_commitment2 = {"commitment": additional_info2} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + { + "UnmintTokens": token_id, + }, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 99}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input, utxo_input2], + input_commitments=[inp_commitment, acc_inp_commitment, inp_commitment2], + outputs=[change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sunmint\stokens", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_freeze_tokens(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An AccountCommand input to freeze the tokens. + And one output to transfer the change coins. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional info (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + {"FreezeToken": [token_id, {"No": None}]}, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 99}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sfreeze\stokens", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_unfreeze_tokens(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An AccountCommand input to unfreeze the tokens. + And one output to transfer the change coins. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional data (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + { + "UnfreezeToken": token_id, + }, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 99}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sunfreeze", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_change_token_authority(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An AccountCommand input to change the token's authority. + And one output to transfer the change coins. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional data (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + { + "ChangeTokenAuthority": [ + token_id, + { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} + } + } + }, + ] + }, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 99}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\schange\stoken", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_change_token_metadata_uri( + backend, scenario_navigator, device, navigator +): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An AccountCommand input to change the token's metadata uri. + And one output to transfer the change coins. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional info (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + { + "ChangeTokenMetadataUri": [ + token_id, + "uri.com".encode(), + ] + }, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 99}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\schange\stoken", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_order_fill(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with 3 inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An account command input to fill an order. + 3. A standard UTXO input to be used for the fill. + And one output to transfer the change coins. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional info (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + fill_amount = 10 + fill_ask = 100 + fill_give = 1000 + + additional_order_info = { + "initially_asked": {"Coin": fill_ask}, + "initially_given": {"TokenV1": [bytes([0] * 32), fill_give]}, + "ask_balance": 0, + "give_balance": 0, + } + order_id = bytes([0] * 32) + account_input = { + "addresses": [], # FillOrder input must not be signed + "input": { + "OrderAccountCommand": [ + { + "FillOrder": [ + order_id, + fill_amount, + ] + }, + additional_order_info, + ] + }, + } + + fill_order_inp_commitment = { + "commitment": { + "FillOrderAccountCommand": [ + additional_order_info["initially_asked"], + additional_order_info["initially_given"], + ] + }, + } + + change_output = { + "output": { + "Transfer": [ + {"Coin": 100 - 1 - fill_amount}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + fill_output = { + "output": { + "Transfer": [ + { + "TokenV1": [ + bytes([0] * 32), + fill_amount * fill_give // fill_ask, + ] + }, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, fill_order_inp_commitment], + outputs=[change_output, fill_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sfill\sorder", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_order_conclude(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An OrderAccountCommand input to conclude an order. + And one output to transfer the change coins + ask balance and another output for the give balance. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional_data (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + initial_ask = 100 + initial_give = 1000 + ask_balance = 10 + give_balance = 900 + + token_id = bytes([1] * 32) + additional_order_info = { + "initially_asked": {"Coin": initial_ask}, + "initially_given": {"TokenV1": [token_id, initial_give]}, + "ask_balance": ask_balance, + "give_balance": give_balance, + } + order_id = bytes([1] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "OrderAccountCommand": [ + { + "ConcludeOrder": order_id, + }, + additional_order_info, + ] + }, + } + + conclude_order_inp_commitment = { + "commitment": { + "ConcludeOrderAccountCommand": [ + additional_order_info["initially_asked"], + additional_order_info["initially_given"], + additional_order_info["ask_balance"], + additional_order_info["give_balance"], + ] + }, + } + + change_output = { + "output": { + "Transfer": [ + {"Coin": 100 - 1 + ask_balance}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + conclude_output = { + "output": { + "Transfer": [ + {"TokenV1": [token_id, give_balance]}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, conclude_order_inp_commitment], + outputs=[change_output, conclude_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sconclude\sorder", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_htlc(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with one input: + 1. The standard UTXO input to pay for tx fees. + And one output to transfer the change coins and the HTLC output. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional info (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + change_output = { + "output": { + "Transfer": [ + {"Coin": 89}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + htlc_output = { + "output": { + "Htlc": [ + {"Coin": 10}, + { + "secret_hash": [0] * 20, + "spend_key": { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)} + } + } + }, + "refund_timelock": {"UntilHeight": 100}, + "refund_key": { + "PublicKey": { + "key": { + "Secp256k1Schnorr": {"pubkey_data": bytes([3] * 33)} + } + } + }, + }, + ], + } + } + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input], + input_commitments=[inp_commitment], + outputs=[htlc_output, change_output], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate\sHTLC", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +def test_sign_tx_without_outputs(backend, scenario_navigator, device, navigator): + """ + Test signing a transaction with two inputs: + 1. A standard UTXO input to pay for tx fees. + 2. An AccountCommand input to freeze the tokens. + And no outputs. + """ + client = MintlayerCommandSender(backend) + h = 1 << 31 + bip44_path = [44 + h, 19788 + h, 0 + h, 0, 0] + + # The additional info (the previous TxOutput that this UTXO input spends) + # This represents an output of 100 coins owned by our key + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 100}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + utxo_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([1] * 32)}, + "index": 0, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + account_nonce = 1 + token_id = bytes([0] * 32) + account_input = { + "addresses": [{"path": bip44_path, "multisig_idx": None}], + "input": { + "AccountCommand": [ + account_nonce, + {"FreezeToken": [token_id, {"No": None}]}, + ] + }, + } + + acc_inp_commitment = {"commitment": {"None": None}} + + transaction = Transaction( + coin=MAINNET, + inputs=[utxo_input, account_input], + input_commitments=[inp_commitment, acc_inp_commitment], + outputs=[], + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=True, + review_custom_screen_text=r"Sign\sfreeze\stokens", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +# Sign a tx with an output large enough to require chunking +def test_sign_tx_with_large_output(backend, scenario_navigator, device, navigator): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + additional_info = { + "Utxo": { + "Transfer": [ + {"Coin": 2000}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + # Make the output big + metadata_uri = b"abcef" * 100 + + # This is an output for issuing an NFT. + # The structure is (TokenId, NftIssuance, Destination) + output = { + "output": { + "IssueNft": [ + bytes([0] * 32), + { + "V0": { + "metadata": { + "creator": { + "public_key": { + "key": { + "Secp256k1Schnorr": { + "pubkey_data": bytes([0] * 33) + } + } + } + }, + "name": b"MyAwesomeNFT", + "description": b"FirstNFT", + "ticker": b"MNFT1", + "icon_uri": b"https://my.nft/icon.png", + "additional_metadata_uri": metadata_uri, + "media_uri": b"https://my.nft/media.jpg", + "media_hash": bytes([0] * 32), + } + } + }, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + + # Sanity check + assert len(sign_tx_next_req_obj.encode({"ProcessOutput": output}).data) > 500 + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\screate\sNFT", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) + + +# Sign a tx with an input and input commitment large enough to require chunking +def test_sign_tx_with_large_input_and_commitment( + backend, scenario_navigator, device, navigator +): + # Use the app interface instead of raw interface + client = MintlayerCommandSender(backend) + h = 1 << 31 + + # Make the additional info big + metadata_uri = b"abcef" * 100 + + # The utxo is for issuing an NFT. + # The structure is (TokenId, NftIssuance, Destination) + token_id = bytes([11] * 32) + additional_info = { + "Utxo": { + "IssueNft": [ + token_id, + { + "V0": { + "metadata": { + "creator": { + "public_key": { + "key": { + "Secp256k1Schnorr": { + "pubkey_data": bytes([0] * 33) + } + } + } + }, + "name": b"MyAwesomeNFT", + "description": b"FirstNFT", + "ticker": b"MNFT1", + "icon_uri": b"https://my.nft/icon.png", + "additional_metadata_uri": metadata_uri, + "media_uri": b"https://my.nft/media.jpg", + "media_hash": bytes([0] * 32), + } + } + }, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([0] * 33)}} + } + }, + ], + } + } + inp = { + "addresses": [{"path": [44 + h, 19788 + h, 0 + h, 0, 0], "multisig_idx": None}], + "input": { + "Utxo": [ + { + "id": {"Transaction": bytes([0] * 32)}, + "index": 1, + }, + additional_info, + ] + }, + } + + inp_commitment = {"commitment": additional_info} + + output = { + "output": { + "Transfer": [ + {"TokenV1": [token_id, 1]}, + { + "PublicKey": { + "key": {"Secp256k1Schnorr": {"pubkey_data": bytes([2] * 33)}} + } + }, + ], + } + } + + # Sanity checks + assert len(sign_tx_next_req_obj.encode({"ProcessInput": inp}).data) > 500 + assert ( + len( + sign_tx_next_req_obj.encode({"ProcessInputCommitment": inp_commitment}).data + ) + > 500 + ) + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + coin=MAINNET, inputs=[inp], input_commitments=[inp_commitment], outputs=[output] + ) + + review_tx = ReviewTransaction( + transaction=transaction, + has_command_input=False, + review_custom_screen_text=r"Sign\stransfer", + ) + sign_tx_review(client, device, navigator, scenario_navigator, review_tx) diff --git a/tests/usage.md b/tests/usage.md index 201d146..fcde929 100644 --- a/tests/usage.md +++ b/tests/usage.md @@ -1,74 +1,91 @@ # How to use the Ragger test framework -This framework allows testing the application on the Speculos emulator or on a real device using LedgerComm or LedgerWallet - +This document describes how to run the Mintlayer Ledger app functional tests with the Ragger test +framework, either on the Speculos emulator or on a physical Ledger device. ## Quickly get started with Ragger and Speculos -### Install ragger and dependencies +### Install Ragger and dependencies -``` -pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt +In this document we'll be running tests outside of a Docker container, in which case additional +dependencies must be installed: + +```bash +pip install -r tests/requirements.txt sudo apt-get update && sudo apt-get install qemu-user-static ``` -### Compile the application +### Build the application -The application to test must be compiled for all required devices. -You can use for this the container `ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite`: -``` -docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest -cd # replace with the name of your app, (eg boilerplate) -docker run --user "$(id -u)":"$(id -g)" --rm -ti -v "$(realpath .):/app" --privileged -v "/dev/bus/usb:/dev/bus/usb" ledger-app-builder-lite:latest -make clean && make BOLOS_SDK=$_SDK # replace with one of [NANOS, NANOX, NANOSP, STAX, FLEX] -exit +Build the app for the device model that will be used by the tests; you can use the image +`ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder` for this: + +```bash +docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest +docker run --user "$(id -u)":"$(id -g)" --rm -ti -v "$(realpath .):/app" -w /app ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest ``` -### Run a simple test using the Speculos emulator +Then, inside the container: -You can use the following command to get your first experience with Ragger and Speculos +```bash +cargo ledger build nanox ``` -pytest -v --tb=short --device nanox --display -``` -Or you can refer to the section `Available pytest options` to configure the options you want to use +ℹ️ `cargo ledger build` accepts `nanox`, `nanosplus`, `stax`, `flex`, and `apex_p`. -### Run a simple test using a real device +ℹ️ Alternatively, the `ledger-app-dev-tools` image can be used. It already contains tools required to run tests +and must be used if you intend to run them inside the Docker container. -The application to test must be loaded and started on a Ledger device plugged in USB. -You can use for this the container `ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite`: -``` -docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest -cd app-/ # replace with the name of your app, (eg boilerplate) -docker run --user "$(id -u)":"$(id -g)" --rm -ti -v "$(realpath .):/app" --privileged -v "/dev/bus/usb:/dev/bus/usb" ledger-app-builder-lite:latest -make clean && make BOLOS_SDK=$_SDK load # replace with one of [NANOS, NANOX, NANOSP, STAX, FLEX] -exit +### Run tests using the Speculos emulator + +Run the functional tests from the repository root: + +```bash +pytest tests/ --tb=short -v --device nanox ``` -You can use the following command to get your first experience with Ragger and Ledgerwallet on a NANOX. -Make sure that the device is plugged, unlocked, and that the tested application is open. +To see the emulator display while tests run, add `--display`: + +```bash +pytest tests/ --tb=short -v --device nanox --display ``` -pytest -v --tb=short --device nanox --backend ledgerwallet + +⚠️ `--device` specifies the Speculos device model and it should match the binary you've built. +Normally, it will be the same as the `cargo` target that you've passed to `cargo ledger build`, +except for `nanosplus`, whose corresponding device model name is `nanosp`. + +### Run tests using a physical Ledger device + +The Mintlayer app must be built, loaded on the device, and opened before running the tests. +See [Loading on device](../README.md#loading-on-device) for platform-specific loading instructions. + +After the app has been installed on the device, run the tests via: +```bash +pytest tests/ --tb=short -v --device nanox --backend ledgerwallet ``` -Or you can refer to the section `Available pytest options` to configure the options you want to use +⚠️ Functional tests expect the device to be seeded with the seed phrase "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about". +If this is not the case, most of the tests will fail. ## Available pytest options -Standard useful pytest options -``` - -v formats the test summary in a readable way - -s enable logs for successful tests, on Speculos it will enable app logs if compiled with DEBUG=1 - -k only run the tests that contain in their names - --tb=short in case of errors, formats the test traceback in a readable way -``` +Standard useful pytest options: -Custom pytest options +```text + -v formats the test summary in a readable way; + -s enables logs for successful tests; on Speculos it enables app logs if compiled with DEBUG=1; + -k only runs the tests which match ; the expression may be a single substring to match + against test names and their parent classes, or a combination of them, e.g. '-k foo' or + '-k "(foo or bar) and not baz"'; + --tb=short formats tracebacks in a compact way; ``` - --device run the test on the specified device [nanos,nanox,nanosp,stax,flex,all]. This parameter is mandatory - --backend run the tests against the backend [speculos, ledgercomm, ledgerwallet]. Speculos is the default - --display on Speculos, enables the display of the app screen using QT - --golden_run on Speculos, screen comparison functions will save the current screen instead of comparing - --log_apdu_file log all apdu exchanges to the file in parameter. The previous file content is erased -``` +Custom pytest options: + +```text + --device run tests on the specified device [nanox,nanosp,stax,flex,apex_p,all]; + --backend run tests against [speculos, ledgercomm, ledgerwallet]; Speculos is the default; + --display on Speculos, show the app screen using QT; + --golden_run save current screens instead of comparing them; + --log_apdu_file log all APDU exchanges to the given file; previous file content is erased; +``` diff --git a/tests/utils.py b/tests/utils.py index cb52233..1d79e50 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,23 +1,3 @@ from pathlib import Path -from hashlib import sha256 -from sha3 import keccak_256 - -from ecdsa.curves import SECP256k1 -from ecdsa.keys import VerifyingKey -from ecdsa.util import sigdecode_der - ROOT_SCREENSHOT_PATH = Path(__file__).parent.resolve() - - -# Check if a signature of a given message is valid -def check_signature_validity(public_key: bytes, signature: bytes, message: bytes) -> bool: - pk: VerifyingKey = VerifyingKey.from_string( - public_key, - curve=SECP256k1, - hashfunc=sha256 - ) - return pk.verify(signature=signature, - data=message, - hashfunc=keccak_256, - sigdecode=sigdecode_der) diff --git a/tools/codecheck.py b/tools/codecheck.py new file mode 100755 index 0000000..847d8ed --- /dev/null +++ b/tools/codecheck.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 + +import itertools +import os +import pathlib +import re +import sys + +PROJECT_ROOT_DIR = pathlib.Path(__file__).resolve().parent.parent + +LICENSE_TEMPLATE1 = [ + r"/\*{77}", + r" \* Mintlayer Ledger App\.", + r" \* \(c\) 202[0-9](-202[0-9])? RBB S\.r\.l\.", + r" \*", + r' \* Licensed under the Apache License, Version 2\.0 \(the "License"\);', + r" \* you may not use this file except in compliance with the License\.", + r" \* You may obtain a copy of the License at", + r" \*", + r" \* http://www\.apache\.org/licenses/LICENSE-2\.0", + r" \*", + r" \* Unless required by applicable law or agreed to in writing, software", + r' \* distributed under the License is distributed on an "AS IS" BASIS,', + r" \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.", + r" \* See the License for the specific language governing permissions and", + r" \* limitations under the License\.", + r" \*{77}/", +] + +LICENSE_TEMPLATE2 = [ + r"/\*{77}", + r" \* Mintlayer Ledger App\.", + r" \* \(c\) 202[0-9](-202[0-9])? Ledger SAS\.", + r" \* \(c\) 202[0-9](-202[0-9])? RBB S\.r\.l\.", + r" \*", + r' \* Licensed under the Apache License, Version 2\.0 \(the "License"\);', + r" \* you may not use this file except in compliance with the License\.", + r" \* You may obtain a copy of the License at", + r" \*", + r" \* http://www\.apache\.org/licenses/LICENSE-2\.0", + r" \*", + r" \* Unless required by applicable law or agreed to in writing, software", + r' \* distributed under the License is distributed on an "AS IS" BASIS,', + r" \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.", + r" \* See the License for the specific language governing permissions and", + r" \* limitations under the License\.", + r" \*{77}/", +] + +COMMON_EXCLUDE_DIRS = ["target", ".git", ".mypy_cache"] + + +# List source files with the given extension. If the extension is None, list all files. +def sources_with_extension(ext: str | None, top_dir=".", exclude=[]): + exclude_full_paths = [ + os.path.normpath(rel_path) for rel_path in COMMON_EXCLUDE_DIRS + exclude + ] + exclude_names = ["__pycache__"] + + def is_excluded(dirpath, entry_name): + return ( + entry_name in exclude_names + or os.path.normpath(os.path.join(dirpath, entry_name).lower()) + in exclude_full_paths + ) + + for dirpath, dirnames, filenames in os.walk(top_dir, topdown=True): + dirnames[:] = [d for d in dirnames if not is_excluded(dirpath, d)] + for filename in filenames: + if not is_excluded(dirpath, filename): + if ext is None or os.path.splitext(filename)[1].lower() == ext: + yield os.path.join(dirpath, filename) + + +# List all files +def all_files(exclude=[]): + return sources_with_extension(None, exclude=exclude) + + +# List Rust source files +def rs_sources(exclude=[]): + return sources_with_extension(".rs", exclude=exclude) + + +# List Cargo config files +def cargo_config_files(exclude=[]): + return sources_with_extension(".toml", exclude=exclude) + + +# List Python source files +def py_sources(exclude=[]): + return sources_with_extension(".py", exclude=exclude) + + +# List GitHub workflow files +def github_workflows(exclude=[]): + return sources_with_extension(".yml", top_dir=".github", exclude=exclude) + + +# Check license header in Rust source files +def check_local_licenses(): + print("==== Checking local license headers:") + + # List of files/dirs excluded from the check + exclude = [] + + template1 = re.compile("(?:" + r")\n(?:".join(LICENSE_TEMPLATE1) + ")") + template2 = re.compile("(?:" + r")\n(?:".join(LICENSE_TEMPLATE2) + ")") + + ok = True + for path in rs_sources(exclude): + with open(path, "r", encoding="utf-8") as file: + file_contents = file.read() + if not (template1.search(file_contents) or template2.search(file_contents)): + ok = False + print("{}: license missing or incorrect".format(path)) + + print() + return ok + + +# Check TODO(PR) and FIXME instances +def check_todos(): + print("==== Checking TODO(PR) and FIXME instances:") + + # List of files/dirs excluded from the check + exclude = [ + # Exclude itself + "tools/codecheck.py", + ] + + ok = True + for path in itertools.chain( + rs_sources(exclude), + cargo_config_files(exclude), + py_sources(exclude), + github_workflows(exclude), + ): + with open(path, "r", encoding="utf-8") as file: + file_data = file.read() + if "TODO(PR)" in file_data or "FIXME" in file_data: + ok = False + print("{}: found TODO(PR) or FIXME instances".format(path)) + + print() + return ok + + +# Check for trailing whitespaces +def check_trailing_whitespaces(): + print("==== Checking for trailing whitespaces:") + + # List of files/dirs excluded from the check + exclude = ["media", "tests/snapshots"] + + ok = True + for path in all_files(exclude): + with open(path, "r", encoding="utf-8") as file: + try: + for line_idx, line in enumerate(file, start=1): + line = line.rstrip("\n\r") + if line != line.rstrip(): + ok = False + print(f"{path}: trailing whitespaces at line {line_idx}") + except: + ok = False + print( + f"{path}: can't check for trailing whitespaces, " + "perhaps the file should be in the 'exclude' list?" + ) + + print() + return ok + + +def run_checks(): + return all( + [ + check_local_licenses(), + check_todos(), + check_trailing_whitespaces(), + ] + ) + + +if __name__ == "__main__": + # Note: this script expects the current directory to be the project root. + os.chdir(PROJECT_ROOT_DIR) + + if not run_checks(): + sys.exit(1) diff --git a/tools/get_target_id.py b/tools/get_target_id.py new file mode 100755 index 0000000..364fc80 --- /dev/null +++ b/tools/get_target_id.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +"""Extract the `ledger.target_id` section from a Ledger app ELF.""" + +import argparse +import sys + +try: + from elftools.elf.elffile import ELFFile +except ModuleNotFoundError as e: + raise SystemExit( + "Missing dependency 'pyelftools'. Install it with: python3 -m pip install pyelftools" + ) from e + + +def get_target_id(elf_path: str) -> str: + with open(elf_path, "rb") as f: + elf = ELFFile(f) + section = elf.get_section_by_name("ledger.target_id") + if section is None: + raise SystemExit(f"Section 'ledger.target_id' not found in {elf_path}") + return section.data().decode("ascii").strip() + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("elf", help="Path to the Ledger app ELF file") + args = parser.parse_args() + + print(get_target_id(args.elf)) + return 0 + + +if __name__ == "__main__": + sys.exit(main())