Repository: LedgerHQ/app-ethereum (language: python)

Issue:
Changelog update & non-dev version number
## Description

Added missing information about the removal of Compound in the changelog file.
Removed the -dev suffix from the app's version ahead for release.

## Changes include

- [ ] Bugfix (non-breaking change that solves an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (change that is not backwards-compatible and/or changes current functionality)
- [ ] Tests
- [x] Documentation
- [ ] Other (for changes that might not fit in any category)


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/build-workflow.yml b/.github/workflows/build-workflow.yml
new file mode 100644
index 000000000..0c9ef5fdd
--- /dev/null
+++ b/.github/workflows/build-workflow.yml
@@ -0,0 +1,56 @@
+name: Compilation
+
+on:
+  workflow_dispatch:
+  push:
+    branches:
+      - master
+  pull_request:
+    branches:
+      - master
+      - develop
+
+jobs:
+  nano_debug_build:
+    name: Build debug application for NanoS, X and S+
+    strategy:
+      matrix:
+        include:
+          - SDK: "$NANOS_SDK"
+            artifact: nanos
+          - SDK: "$NANOX_SDK"
+            artifact: nanox
+          - SDK: "$NANOSP_SDK"
+            artifact: nanosp
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
+
+    steps:
+      - name: Clone
+        uses: actions/checkout@v2
+        with:
+          submodules: recursive
+
+      - name: Build an altcoin
+        run: |
+          make BOLOS_SDK=${{ matrix.SDK }} DEBUG=1 ALLOW_DATA=1 CHAIN=ethereum_classic
+          mv bin/app.elf ethereum_classic_${{ matrix.artifact }}.elf
+
+      - name: Upload altcoin binary
+        uses: actions/upload-artifact@v2
+        with:
+          name: ethereum_classic_${{ matrix.artifact }}
+          path: ./ethereum_classic_${{ matrix.artifact }}.elf
+
+      - name: Build Ethereum
+        run: |
+          make clean
+          make BOLOS_SDK=${{ matrix.SDK }} DEBUG=1 ALLOW_DATA=1
+          mv bin/app.elf ethereum_${{ matrix.artifact }}.elf
+
+      - name: Upload app binary
+        uses: actions/upload-artifact@v2
+        with:
+          name: ethereum_${{ matrix.artifact }}
+          path: ./ethereum_${{ matrix.artifact }}.elf
\ No newline at end of file
diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml
index c3f4562b0..85efce856 100644
--- a/.github/workflows/ci-workflow.yml
+++ b/.github/workflows/ci-workflow.yml
@@ -1,4 +1,4 @@
-name: Compilation & tests
+name: Tests
 
 on:
   workflow_dispatch:
@@ -11,79 +11,6 @@ on:
       - develop
 
 jobs:
-  job_build_debug_nano_s:
-    name: Build debug Nano S
-    runs-on: ubuntu-latest
-
-    container:
-      image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
-
-    steps:
-      - name: Clone
-        uses: actions/checkout@v2
-        with:
-          submodules: recursive
-
-      - name: Build an altcoin
-        run: |
-          make DEBUG=1 ALLOW_DATA=1 CHAIN=ethereum_classic
-          mv bin/app.elf ethereum_classic_nanos.elf
-
-      - name: Upload altcoin binary
-        uses: actions/upload-artifact@v2
-        with:
-          name: ethereum_classic_nanos
-          path: ./ethereum_classic_nanos.elf
-
-      - name: Build Ethereum
-        run: |
-          make clean
-          make DEBUG=1 ALLOW_DATA=1
-          mv bin/app.elf ethereum_nanos.elf
-
-      - name: Upload app binary
-        uses: actions/upload-artifact@v2
-        with:
-          name: ethereum_nanos
-          path: ./ethereum_nanos.elf
-
-  job_build_debug_nano_x:
-    name: Build debug Nano X
-    runs-on: ubuntu-latest
-
-    container:
-      image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
-
-    steps:
-      - name: Clone
-        uses: actions/checkout@v2
-        with:
-          submodules: recursive
-
-      - name: Build an altcoin Nano X
-        run: |
-          make clean
-          make BOLOS_SDK=$NANOX_SDK DEBUG=1 ALLOW_DATA=1 CHAIN=ethereum_classic
-          mv bin/app.elf ethereum_classic_nanox.elf
-
-      - name: Upload altcoin binary
-        uses: actions/upload-artifact@v2
-        with:
-          name: ethereum_classic_nanox
-          path: ./ethereum_classic_nanox.elf
-
-      - name: Build Ethereum Nano X
-        run: |
-          make clean
-          make BOLOS_SDK=$NANOX_SDK DEBUG=1 ALLOW_DATA=1
-          mv bin/app.elf ethereum_nanox.elf
-
-      - name: Upload app binary
-        uses: actions/upload-artifact@v2
-        with:
-          name: ethereum_nanox
-          path: ./ethereum_nanox.elf
-
   scan-build:
     name: Clang Static Analyzer
     runs-on: ubuntu-latest
@@ -104,8 +31,12 @@ jobs:
           name: scan-build
           path: scan-build
 
-  building_for_e2e_tests:
-    name: Building binaries for E2E tests
+# =====================================================
+#            ZEMU TESTS
+# =====================================================
+
+  building_for_e2e_zemu_tests:
+    name: Building binaries for E2E Zemu tests
     runs-on: ubuntu-latest
     container:
       image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
@@ -114,17 +45,19 @@ jobs:
       - uses: actions/checkout@v2
 
       - name: Build testing binaries
-        run: cd tests && ./build_local_test_elfs.sh
+        run: |
+          git config --global --add safe.directory "$GITHUB_WORKSPACE"
+          cd tests/zemu/ && ./build_local_test_elfs.sh
 
       - name: Upload app binaries
         uses: actions/upload-artifact@v2
         with:
           name: e2e_elfs
-          path: ./tests/elfs/
+          path: ./tests/zemu/elfs/
 
-  jobs-e2e-tests:
-    name: E2E tests
-    needs: [building_for_e2e_tests]
+  jobs-e2e-zemu-tests:
+    name: E2E Zemu tests
+    needs: [building_for_e2e_zemu_tests]
     runs-on: ubuntu-latest
     steps:
       - name: Test
@@ -146,10 +79,10 @@ jobs:
         run: npm install -g yarn
 
       - name: Build/Install build js deps
-        run: cd tests && yarn install
+        run: cd tests/zemu/ && yarn install
 
       - name: Create tmp folder for artifacts
-        run: mkdir tests/elfs
+        run: mkdir tests/zemu/elfs
 
       - name: Download app binaries
         uses: actions/download-artifact@v2
@@ -157,7 +90,70 @@ jobs:
           path: tmp/
 
       - name: Gather elfs
-        run: cp `find tmp/e2e_elfs/ -name "*.elf"` tests/elfs/
+        run: cp `find tmp/e2e_elfs/ -name "*.elf"` tests/zemu/elfs/
 
       - name: Run zemu tests
-        run: cd tests && yarn test
+        run: cd tests/zemu/ && yarn test
+
+# =====================================================
+#            SPECULOS TESTS
+# =====================================================
+
+
+  building_for_e2e_speculos_tests:
+    name: Building binaries for E2E Speculos tests
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Build testing binaries
+        run: |
+          mkdir tests/speculos/elfs
+          make clean && make DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf
+          make clean && make DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf
+          make clean && make DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf
+
+      - name: Upload app binaries
+        uses: actions/upload-artifact@v2
+        with:
+          name: e2e_elfs
+          path: ./tests/speculos/elfs
+
+
+  jobs-e2e-speculos-tests:
+    name: Speculos tests
+    strategy:
+      matrix:
+        model: ["nanosp", "nanos", "nanox"]     
+         
+    needs: [building_for_e2e_speculos_tests]
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Clone
+        uses: actions/checkout@v2
+
+      - name: Create tmp folder for artifacts
+        run: mkdir tests/speculos/elfs
+
+      - name: Download app binaries
+        uses: actions/download-artifact@v2
+        with:
+          path: tmp/
+
+      - name: Gather elfs
+        run: cp `find tmp/e2e_elfs/ -name "*.elf"` tests/speculos/elfs/
+
+      - name: Install dependencies
+        run: |
+          cd tests/speculos
+          sudo apt-get update && sudo apt-get install -y qemu-user-static
+          pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt
+
+      - name: Run speculos tests
+        run: | 
+          cd tests/speculos
+          pytest --model ${{ matrix.model }} --path ./elfs/${{ matrix.model }}.elf --display headless
\ No newline at end of file
diff --git a/.github/workflows/lint-workflow.yml b/.github/workflows/lint-workflow.yml
index b9ea676c6..f74416dc0 100644
--- a/.github/workflows/lint-workflow.yml
+++ b/.github/workflows/lint-workflow.yml
@@ -19,8 +19,8 @@ jobs:
         uses: actions/checkout@v2
 
       - name: Lint
-        uses: DoozyX/clang-format-lint-action@v0.13
+        uses: DoozyX/clang-format-lint-action@v0.14
         with:
           source: "./"
           extensions: "h,c"
-          clangFormatVersion: 12.0.0
+          clangFormatVersion: 12.0.1
diff --git a/.gitignore b/.gitignore
index 16c938c53..9443644b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ tests/elfs/*
 tests/snapshots-tmp
 
 .vscode
+.idea
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 935cc0066..79d9d0b4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## [1.9.20](https://github.com/ledgerhq/app-ethereum/compare/1.9.19...1.9.20) - 2022-10-10
+
+### Added
+
+- (clone) XDCNetwork
+- (clone) Meter
+- (clone) Multivac
+- (clone) Tecra
+- (clone) ApothemNetwork
+
+### Changed
+
+- EIP-191 improvements, now lets the user see the entire message one chunk at a time (255 characters for LNX & LNS+, 99 for LNS)
+
+### Fixed
+
+- Allow swap with variants
+
+### Removed
+
+- Compound support (will become its own plugin)
+
 ## [1.9.19](https://github.com/ledgerhq/app-ethereum/compare/1.9.18...1.9.19) - 2022-06-15
 
 ### Added
@@ -16,7 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Changed
 
-- EIP-191 signatures now show (up to 99 characters on LNS and 255 on LNX & LNS) the actual data contained in the message (clear-signing)
+- EIP-191 signatures now show (up to 99 characters on LNS and 255 on LNX & LNS+) the actual data contained in the message (clear-signing)
 
 ### Fixed
 
@@ -64,7 +86,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Fixed
 
-- Fixed stark order signature on LNS 
+- Fixed stark order signature on LNS
 
 ## [1.9.13](https://github.com/ledgerhq/app-ethereum/compare/1.9.12...1.9.13) - 2021-11-17
 
@@ -76,7 +98,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Fixed
 
-- Fixed stark order signature on LNX 
+- Fixed stark order signature on LNX
 
 ## [1.9.11](https://github.com/ledgerhq/app-ethereum/compare/1.9.10...1.9.11) - 2021-10-12
 
diff --git a/Makefile b/Makefile
index f9af42aed..eedf8480a 100644
--- a/Makefile
+++ b/Makefile
@@ -34,9 +34,9 @@ APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
 
 APPVERSION_M=1
 APPVERSION_N=9
-APPVERSION_P=19
+APPVERSION_P=20
 APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
-APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION)
+APP_LOAD_FLAGS= --appFlags 0xa40 --dep Ethereum:$(APPVERSION)
 
 ###########################
 # Set Chain environnement #
@@ -194,6 +194,7 @@ SDK_SOURCE_PATH  += lib_ux
 ifeq ($(TARGET_NAME),TARGET_NANOX)
 SDK_SOURCE_PATH  += lib_blewbxx lib_blewbxx_impl
 endif
+APP_SOURCE_PATH  += src_bagl
 
 ### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed
 ifeq ($(CHAIN),ethereum)
@@ -222,13 +223,16 @@ delete:
 	python3 -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)
 
 install_tests:
-	cd tests && (yarn install || sudo yarn install)
+	cd tests/zemu/ && (yarn install || sudo yarn install)
 
 run_tests:
-	cd tests && (yarn test || sudo yarn test)
+	cd tests/zemu/ && (yarn test || sudo yarn test)
 
 test: install_tests run_tests
 
+unit-test:
+	make -C tests/unit
+
 # import generic rules from the sdk
 include $(BOLOS_SDK)/Makefile.rules
 
diff --git a/doc/ethapp.asc b/doc/ethapp.asc
index 496ed0e08..839e70b72 100644
--- a/doc/ethapp.asc
+++ b/doc/ethapp.asc
@@ -94,6 +94,8 @@ The address can be optionally checked on the device before being returned.
 
 #### Description
 
+https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md
+
 This command signs an Ethereum transaction after having the user validate the following parameters
 
   - Gas price 
diff --git a/icons/nanos_app_apothemnetwork.gif b/icons/nanos_app_apothemnetwork.gif
new file mode 100644
index 000000000..cccda601d
Binary files /dev/null and b/icons/nanos_app_apothemnetwork.gif differ
diff --git a/icons/nanos_app_meter.gif b/icons/nanos_app_meter.gif
new file mode 100644
index 000000000..7da65b4f9
Binary files /dev/null and b/icons/nanos_app_meter.gif differ
diff --git a/icons/nanos_app_multivac.gif b/icons/nanos_app_multivac.gif
new file mode 100644
index 000000000..f8853eb2b
Binary files /dev/null and b/icons/nanos_app_multivac.gif differ
diff --git a/icons/nanos_app_tecracoin.gif b/icons/nanos_app_tecracoin.gif
new file mode 100755
index 000000000..367ccf4e0
Binary files /dev/null and b/icons/nanos_app_tecracoin.gif differ
diff --git a/icons/nanos_app_xdcnetwork.gif b/icons/nanos_app_xdcnetwork.gif
new file mode 100644
index 000000000..cccda601d
Binary files /dev/null and b/icons/nanos_app_xdcnetwork.gif differ
diff --git a/icons/nanox_app_apothemnetwork.gif b/icons/nanox_app_apothemnetwork.gif
new file mode 100644
index 000000000..387354d90
Binary files /dev/null and b/icons/nanox_app_apothemnetwork.gif differ
diff --git a/icons/nanox_app_meter.gif b/icons/nanox_app_meter.gif
new file mode 100644
index 000000000..d67c25f3a
Binary files /dev/null and b/icons/nanox_app_meter.gif differ
diff --git a/icons/nanox_app_multivac.gif b/icons/nanox_app_multivac.gif
new file mode 100644
index 000000000..77bf0f0d3
Binary files /dev/null and b/icons/nanox_app_multivac.gif differ
diff --git a/icons/nanox_app_tecracoin.gif b/icons/nanox_app_tecracoin.gif
new file mode 100755
index 000000000..596fa3899
Binary files /dev/null and b/icons/nanox_app_tecracoin.gif differ
diff --git a/icons/nanox_app_xdcnetwork.gif b/icons/nanox_app_xdcnetwork.gif
new file mode 100644
index 000000000..387354d90
Binary files /dev/null and b/icons/nanox_app_xdcnetwork.gif differ
diff --git a/makefile_conf/chain/apothemnetwork.mk b/makefile_conf/chain/apothemnetwork.mk
new file mode 100644
index 000000000..23816b5ab
--- /dev/null
+++ b/makefile_conf/chain/apothemnetwork.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/550'"
+DEFINES += CHAINID_UPCASE=\"APOTHEMNETWORK\" CHAINID_COINNAME=\"TXDC\" CHAIN_KIND=CHAIN_KIND_APOTHEMNETWORK CHAIN_ID=51
+APPNAME = "ApothemNetwork"
diff --git a/makefile_conf/chain/meter.mk b/makefile_conf/chain/meter.mk
new file mode 100644
index 000000000..fcf2f364f
--- /dev/null
+++ b/makefile_conf/chain/meter.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/60'"
+DEFINES += CHAINID_UPCASE=\"METER\" CHAINID_COINNAME=\"MTR\" CHAIN_KIND=CHAIN_KIND_METER CHAIN_ID=82
+APPNAME = "Meter"
\ No newline at end of file
diff --git a/makefile_conf/chain/multivac.mk b/makefile_conf/chain/multivac.mk
new file mode 100644
index 000000000..043299b43
--- /dev/null
+++ b/makefile_conf/chain/multivac.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/60'"
+DEFINES += CHAINID_UPCASE=\"MULTIVAC\" CHAINID_COINNAME=\"MTV\" CHAIN_KIND=CHAIN_KIND_MULTIVAC CHAIN_ID=62621
+APPNAME = "MultiVAC"
diff --git a/makefile_conf/chain/tecracoin.mk b/makefile_conf/chain/tecracoin.mk
new file mode 100644
index 000000000..e51df374a
--- /dev/null
+++ b/makefile_conf/chain/tecracoin.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/554'"  --path "44'/60'"
+DEFINES += CHAINID_UPCASE=\"TECRA\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531812
+APPNAME = "TecraCoin"
\ No newline at end of file
diff --git a/makefile_conf/chain/xdcnetwork.mk b/makefile_conf/chain/xdcnetwork.mk
new file mode 100644
index 000000000..0bea527e4
--- /dev/null
+++ b/makefile_conf/chain/xdcnetwork.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/550'"
+DEFINES += CHAINID_UPCASE=\"XDCNETWORK\" CHAINID_COINNAME=\"XDC\" CHAIN_KIND=CHAIN_KIND_XDCNETWORK CHAIN_ID=50
+APPNAME = "XDC Network"
\ No newline at end of file
diff --git a/src/apdu_constants.h b/src/apdu_constants.h
index 9ef49d9ad..219b7d019 100644
--- a/src/apdu_constants.h
+++ b/src/apdu_constants.h
@@ -58,66 +58,67 @@
 #define OFFSET_LC    4
 #define OFFSET_CDATA 5
 
+#define ERR_APDU_EMPTY         0x6982
+#define ERR_APDU_SIZE_MISMATCH 0x6983
+
 void handleGetPublicKey(uint8_t p1,
                         uint8_t p2,
-                        uint8_t *dataBuffer,
+                        const uint8_t *dataBuffer,
                         uint16_t dataLength,
                         unsigned int *flags,
                         unsigned int *tx);
 void handleProvideErc20TokenInformation(uint8_t p1,
                                         uint8_t p2,
-                                        uint8_t *dataBuffer,
+                                        const uint8_t *dataBuffer,
                                         uint16_t dataLength,
                                         unsigned int *flags,
                                         unsigned int *tx);
 void handleProvideNFTInformation(uint8_t p1,
                                  uint8_t p2,
-                                 uint8_t *dataBuffer,
+                                 const uint8_t *dataBuffer,
                                  uint16_t dataLength,
                                  unsigned int *flags,
                                  unsigned int *tx);
 void handleSign(uint8_t p1,
                 uint8_t p2,
-                uint8_t *dataBuffer,
+                const uint8_t *dataBuffer,
                 uint16_t dataLength,
                 unsigned int *flags,
                 unsigned int *tx);
 void handleGetAppConfiguration(uint8_t p1,
                                uint8_t p2,
-                               uint8_t *dataBuffer,
+                               const uint8_t *dataBuffer,
                                uint16_t dataLength,
                                unsigned int *flags,
                                unsigned int *tx);
-void handleSignPersonalMessage(uint8_t p1,
+bool handleSignPersonalMessage(uint8_t p1,
                                uint8_t p2,
-                               uint8_t *dataBuffer,
-                               uint16_t dataLength,
-                               unsigned int *flags,
-                               unsigned int *tx);
+                               const uint8_t *const payload,
+                               uint8_t length);
 void handleSignEIP712Message(uint8_t p1,
                              uint8_t p2,
-                             uint8_t *dataBuffer,
+                             const uint8_t *dataBuffer,
                              uint16_t dataLength,
                              unsigned int *flags,
                              unsigned int *tx);
 
 void handleSetExternalPlugin(uint8_t p1,
                              uint8_t p2,
-                             uint8_t *workBuffer,
+                             const uint8_t *workBuffer,
                              uint16_t dataLength,
                              unsigned int *flags,
                              unsigned int *tx);
 
 void handleSetPlugin(uint8_t p1,
                      uint8_t p2,
-                     uint8_t *workBuffer,
+                     const uint8_t *workBuffer,
                      uint16_t dataLength,
                      unsigned int *flags,
                      unsigned int *tx);
 
 void handlePerformPrivacyOperation(uint8_t p1,
                                    uint8_t p2,
-                                   uint8_t *workBuffer,
+                                   const uint8_t *workBuffer,
                                    uint16_t dataLength,
                                    unsigned int *flags,
                                    unsigned int *tx);
@@ -126,7 +127,7 @@ void handlePerformPrivacyOperation(uint8_t p1,
 
 void handleGetEth2PublicKey(uint8_t p1,
                             uint8_t p2,
-                            uint8_t *dataBuffer,
+                            const uint8_t *dataBuffer,
                             uint16_t dataLength,
                             unsigned int *flags,
                             unsigned int *tx);
@@ -143,7 +144,7 @@ void handleSetEth2WinthdrawalIndex(uint8_t p1,
 
 void handleStarkwareGetPublicKey(uint8_t p1,
                                  uint8_t p2,
-                                 uint8_t *dataBuffer,
+                                 const uint8_t *dataBuffer,
                                  uint16_t dataLength,
                                  unsigned int *flags,
                                  unsigned int *tx);
@@ -155,13 +156,13 @@ void handleStarkwareSignMessage(uint8_t p1,
                                 unsigned int *tx);
 void handleStarkwareProvideQuantum(uint8_t p1,
                                    uint8_t p2,
-                                   uint8_t *dataBuffer,
+                                   const uint8_t *dataBuffer,
                                    uint16_t dataLength,
                                    unsigned int *flags,
                                    unsigned int *tx);
 void handleStarkwareUnsafeSign(uint8_t p1,
                                uint8_t p2,
-                               uint8_t *dataBuffer,
+                               const uint8_t *dataBuffer,
                                uint16_t dataLength,
                                unsigned int *flags,
                                unsigned int *tx);
diff --git a/src/chainConfig.h b/src/chainConfig.h
index 155e3355e..ab91aa603 100644
--- a/src/chainConfig.h
+++ b/src/chainConfig.h
@@ -67,7 +67,12 @@ typedef enum chain_kind_e {
     CHAIN_KIND_OKC,
     CHAIN_KIND_CUBE,
     CHAIN_KIND_SHIDEN,
-    CHAIN_KIND_ASTAR
+    CHAIN_KIND_ASTAR,
+    CHAIN_KIND_XDCNETWORK,
+    CHAIN_KIND_METER,
+    CHAIN_KIND_MULTIVAC,
+    CHAIN_KIND_TECRA,
+    CHAIN_KIND_APOTHEMNETWORK
 } chain_kind_t;
 
 typedef struct chain_config_s {
diff --git a/src/common_ui.h b/src/common_ui.h
new file mode 100644
index 000000000..3bca6b959
--- /dev/null
+++ b/src/common_ui.h
@@ -0,0 +1,31 @@
+#ifndef _COMMON_UI_H_
+#define _COMMON_UI_H_
+
+#include <stdbool.h>
+
+void ui_idle(void);
+void ui_warning_contract_data(void);
+void ui_display_public_eth2(void);
+void ui_display_privacy_public_key(void);
+void ui_display_privacy_shared_secret(void);
+void ui_display_public_key(void);
+void ui_display_sign(void);
+void ui_sign_712_v0(void);
+void ui_display_stark_public(void);
+void ui_confirm_selector(void);
+void ui_confirm_parameter(void);
+void ui_stark_limit_order(void);
+void ui_stark_unsafe_sign(void);
+void ui_stark_transfer(bool selfTransfer, bool conditional);
+
+// EIP-191
+void ui_191_start(void);
+void ui_191_switch_to_message(void);
+void ui_191_switch_to_message_end(void);
+void ui_191_switch_to_sign(void);
+void ui_191_switch_to_question(void);
+
+#include "ui_callbacks.h"
+#include <string.h>
+
+#endif  // _COMMON_UI_H_
diff --git a/src/eth_plugin_handler.c b/src/eth_plugin_handler.c
index f1944efec..22ffbe8f2 100644
--- a/src/eth_plugin_handler.c
+++ b/src/eth_plugin_handler.c
@@ -5,7 +5,9 @@
 #include "network.h"
 #include "ethUtils.h"
 
-void eth_plugin_prepare_init(ethPluginInitContract_t *init, uint8_t *selector, uint32_t dataSize) {
+void eth_plugin_prepare_init(ethPluginInitContract_t *init,
+                             const uint8_t *selector,
+                             uint32_t dataSize) {
     memset((uint8_t *) init, 0, sizeof(ethPluginInitContract_t));
     init->selector = selector;
     init->dataSize = dataSize;
@@ -111,7 +113,7 @@ static bool eth_plugin_perform_init_old_internal(uint8_t *contractAddress,
              j++) {
             if (memcmp(init->selector, (const void *) PIC(selectors[j]), SELECTOR_SIZE) == 0) {
                 if ((INTERNAL_ETH_PLUGINS[i].availableCheck == NULL) ||
-                    ((PluginAvailableCheck) PIC(INTERNAL_ETH_PLUGINS[i].availableCheck)) ()) {
+                    ((PluginAvailableCheck) PIC(INTERNAL_ETH_PLUGINS[i].availableCheck))()) {
                     strlcpy(dataContext.tokenContext.pluginName,
                             INTERNAL_ETH_PLUGINS[i].alias,
                             PLUGIN_ID_LENGTH);
@@ -346,13 +348,13 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
             }
             break;
         case ETH_PLUGIN_QUERY_CONTRACT_ID:
-            if (((ethQueryContractID_t *) parameter)->result <= ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
-                return ETH_PLUGIN_RESULT_UNAVAILABLE;
+            if (((ethQueryContractID_t *) parameter)->result != ETH_PLUGIN_RESULT_OK) {
+                return ETH_PLUGIN_RESULT_ERROR;
             }
             break;
         case ETH_PLUGIN_QUERY_CONTRACT_UI:
-            if (((ethQueryContractUI_t *) parameter)->result <= ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
-                return ETH_PLUGIN_RESULT_UNAVAILABLE;
+            if (((ethQueryContractUI_t *) parameter)->result != ETH_PLUGIN_RESULT_OK) {
+                return ETH_PLUGIN_RESULT_ERROR;
             }
             break;
         default:
diff --git a/src/eth_plugin_handler.h b/src/eth_plugin_handler.h
index ba6ffeefd..28b13fbeb 100644
--- a/src/eth_plugin_handler.h
+++ b/src/eth_plugin_handler.h
@@ -6,7 +6,9 @@
 #define NO_EXTRA_INFO(ctx, idx) \
     (allzeroes(&(ctx.transactionContext.extraInfo[idx]), sizeof(extraInfo_t)))
 
-void eth_plugin_prepare_init(ethPluginInitContract_t *init, uint8_t *selector, uint32_t dataSize);
+void eth_plugin_prepare_init(ethPluginInitContract_t *init,
+                             const uint8_t *selector,
+                             uint32_t dataSize);
 void eth_plugin_prepare_provide_parameter(ethPluginProvideParameter_t *provideParameter,
                                           uint8_t *parameter,
                                           uint32_t parameterOffset);
diff --git a/src/eth_plugin_internal.c b/src/eth_plugin_internal.c
index 0e28ca601..b266969e4 100644
--- a/src/eth_plugin_internal.c
+++ b/src/eth_plugin_internal.c
@@ -4,7 +4,6 @@
 bool erc20_plugin_available_check(void);
 
 void erc20_plugin_call(int message, void* parameters);
-void compound_plugin_call(int message, void* parameters);
 
 void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) {
     uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH);
@@ -29,17 +28,6 @@ static const uint8_t ERC20_APPROVE_SELECTOR[SELECTOR_SIZE] = {0x09, 0x5e, 0xa7,
 const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS] = {ERC20_TRANSFER_SELECTOR,
                                                              ERC20_APPROVE_SELECTOR};
 
-static const uint8_t COMPOUND_REDEEM_UNDERLYING_SELECTOR[SELECTOR_SIZE] = {0x85, 0x2a, 0x12, 0xe3};
-static const uint8_t COMPOUND_REDEEM_SELECTOR[SELECTOR_SIZE] = {0xdb, 0x00, 0x6a, 0x75};
-static const uint8_t COMPOUND_MINT_SELECTOR[SELECTOR_SIZE] = {0xa0, 0x71, 0x2d, 0x68};
-static const uint8_t CETH_MINT_SELECTOR[SELECTOR_SIZE] = {0x12, 0x49, 0xc5, 0x8b};
-
-const uint8_t* const COMPOUND_SELECTORS[NUM_COMPOUND_SELECTORS] = {
-    COMPOUND_REDEEM_UNDERLYING_SELECTOR,
-    COMPOUND_REDEEM_SELECTOR,
-    COMPOUND_MINT_SELECTOR,
-    CETH_MINT_SELECTOR};
-
 #ifdef HAVE_ETH2
 
 static const uint8_t ETH2_DEPOSIT_SELECTOR[SELECTOR_SIZE] = {0x22, 0x89, 0x51, 0x18};
@@ -111,12 +99,6 @@ const internalEthPlugin_t INTERNAL_ETH_PLUGINS[] = {
      "-erc20",
      erc20_plugin_call},
 
-    {NULL,
-     (const uint8_t**) COMPOUND_SELECTORS,
-     NUM_COMPOUND_SELECTORS,
-     "-cmpd",
-     compound_plugin_call},
-
 #ifdef HAVE_ETH2
 
     {NULL, (const uint8_t**) ETH2_SELECTORS, NUM_ETH2_SELECTORS, "-eth2", eth2_plugin_call},
diff --git a/src/eth_plugin_internal.h b/src/eth_plugin_internal.h
index 4d26130a2..1ad8382d1 100644
--- a/src/eth_plugin_internal.h
+++ b/src/eth_plugin_internal.h
@@ -29,9 +29,6 @@ typedef struct internalEthPlugin_t {
 #define NUM_ERC20_SELECTORS 2
 extern const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS];
 
-#define NUM_COMPOUND_SELECTORS 4
-extern const uint8_t* const COMPOUND_SELECTORS[NUM_COMPOUND_SELECTORS];
-
 #ifdef HAVE_ETH2
 
 #define NUM_ETH2_SELECTORS 1
diff --git a/src/eth_plugin_ui.c b/src/eth_plugin_ui.c
index 681ef664f..d4bdc1528 100644
--- a/src/eth_plugin_ui.c
+++ b/src/eth_plugin_ui.c
@@ -1,8 +1,4 @@
 #include "shared_context.h"
-#ifdef HAVE_UX_FLOW
-#include "ui_flow.h"
-#endif
-#include "ui_callbacks.h"
 #include "eth_plugin_handler.h"
 #include "ux.h"
 #include "feature_signTx.h"
diff --git a/src/main.c b/src/main.c
index 8b029fa85..2a32e224c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,8 +17,7 @@
 
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_callbacks.h"
-#include "ui_flow.h"
+#include "common_ui.h"
 
 #include "os_io_seproxyhal.h"
 
@@ -84,24 +83,6 @@ void reset_app_context() {
     memset((uint8_t *) &tmpContent, 0, sizeof(tmpContent));
 }
 
-void ui_idle(void) {
-    // reserve a display stack slot if none yet
-    if (G_ux.stack_count == 0) {
-        ux_stack_push();
-    }
-    ux_flow_init(0, ux_idle_flow, NULL);
-}
-
-void ui_warning_contract_data(void) {
-    ux_flow_init(0, ux_warning_contract_data_flow, NULL);
-}
-
-unsigned int io_seproxyhal_touch_exit(__attribute__((unused)) const bagl_element_t *e) {
-    // Go back to the dashboard
-    os_sched_exit(0);
-    return 0;  // do not redraw the widget
-}
-
 void io_seproxyhal_send_status(uint32_t sw) {
     G_io_apdu_buffer[0] = ((sw >> 8) & 0xff);
     G_io_apdu_buffer[1] = (sw & 0xff);
@@ -296,6 +277,21 @@ extraInfo_t *getKnownToken(uint8_t *contractAddress) {
         case CHAIN_KIND_ASTAR:
             numTokens = NUM_TOKENS_ASTAR;
             break;
+        case CHAIN_KIND_XDCNETWORK:
+            numTokens = NUM_TOKENS_XDCNETWORK;
+            break;
+        case CHAIN_KIND_METER:
+            numTokens = NUM_TOKENS_METER;
+            break;
+        case CHAIN_KIND_MULTIVAC:
+            numTokens = NUM_TOKENS_MULTIVAC;
+            break;
+        case CHAIN_KIND_TECRA:
+            numTokens = NUM_TOKENS_TECRA;
+            break;
+        case CHAIN_KIND_APOTHEMNETWORK:
+            numTokens = NUM_TOKENS_APOTHEMNETWORK;
+            break;
     }
     for (i = 0; i < numTokens; i++) {
         switch (chainConfig->kind) {
@@ -434,6 +430,21 @@ extraInfo_t *getKnownToken(uint8_t *contractAddress) {
             case CHAIN_KIND_ASTAR:
                 currentToken = (tokenDefinition_t *) PIC(&TOKENS_ASTAR[i]);
                 break;
+            case CHAIN_KIND_XDCNETWORK:
+                currentToken = (tokenDefinition_t *) PIC(&TOKENS_XDCNETWORK[i]);
+                break;
+            case CHAIN_KIND_METER:
+                currentToken = (tokenDefinition_t *) PIC(&TOKENS_METER[i]);
+                break;
+            case CHAIN_KIND_MULTIVAC:
+                currentToken = (tokenDefinition_t *) PIC(&TOKENS_MULTIVAC[i]);
+                break;
+            case CHAIN_KIND_TECRA:
+                currentToken = (tokenDefinition_t *) PIC(&TOKENS_TECRA[i]);
+                break;
+            case CHAIN_KIND_APOTHEMNETWORK:
+                currentToken = (tokenDefinition_t *) PIC(&TOKENS_APOTHEMNETWORK[i]);
+                break;
         }
         if (memcmp(currentToken->address, tmpContent.txContent.destination, ADDRESS_LENGTH) == 0) {
             return currentToken;
@@ -480,6 +491,36 @@ void handleGetWalletId(volatile unsigned int *tx) {
 
 #endif  // HAVE_WALLET_ID_SDK
 
+const uint8_t *parseBip32(const uint8_t *dataBuffer, uint16_t *dataLength, bip32_path_t *bip32) {
+    if (*dataLength < 1) {
+        PRINTF("Invalid data\n");
+        return NULL;
+    }
+
+    bip32->length = *dataBuffer;
+
+    if (bip32->length < 0x1 || bip32->length > MAX_BIP32_PATH) {
+        PRINTF("Invalid bip32\n");
+        return NULL;
+    }
+
+    dataBuffer++;
+    (*dataLength)--;
+
+    if (*dataLength < sizeof(uint32_t) * (bip32->length)) {
+        PRINTF("Invalid data\n");
+        return NULL;
+    }
+
+    for (uint8_t i = 0; i < bip32->length; i++) {
+        bip32->path[i] = U4BE(dataBuffer, 0);
+        dataBuffer += sizeof(uint32_t);
+        *dataLength -= sizeof(uint32_t);
+    }
+
+    return dataBuffer;
+}
+
 void handleApdu(unsigned int *flags, unsigned int *tx) {
     unsigned short sw = 0;
 
@@ -623,12 +664,11 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
 
                 case INS_SIGN_PERSONAL_MESSAGE:
                     memset(tmpCtx.transactionContext.tokenSet, 0, MAX_ITEMS);
+                    *flags |= IO_ASYNCH_REPLY;
                     handleSignPersonalMessage(G_io_apdu_buffer[OFFSET_P1],
                                               G_io_apdu_buffer[OFFSET_P2],
                                               G_io_apdu_buffer + OFFSET_CDATA,
-                                              G_io_apdu_buffer[OFFSET_LC],
-                                              flags,
-                                              tx);
+                                              G_io_apdu_buffer[OFFSET_LC]);
                     break;
 
                 case INS_SIGN_EIP_712_MESSAGE:
@@ -730,9 +770,11 @@ void app_main(void) {
                 // no apdu received, well, reset the session, and reset the
                 // bootloader configuration
                 if (rx == 0) {
-                    THROW(0x6982);
+                    THROW(ERR_APDU_EMPTY);
+                }
+                if (rx > OFFSET_LC && rx != (G_io_apdu_buffer[OFFSET_LC] + 5)) {
+                    THROW(ERR_APDU_SIZE_MISMATCH);
                 }
-                PRINTF("New APDU received:\n%.*H\n", rx, G_io_apdu_buffer);
 
                 handleApdu(&flags, &tx);
             }
diff --git a/src/shared_context.h b/src/shared_context.h
index ef418fede..424c0faee 100644
--- a/src/shared_context.h
+++ b/src/shared_context.h
@@ -18,6 +18,11 @@
 
 #define N_storage (*(volatile internalStorage_t *) PIC(&N_storage_real))
 
+typedef struct bip32_path_t {
+    uint8_t length;
+    uint32_t path[MAX_BIP32_PATH];
+} bip32_path_t;
+
 typedef struct internalStorage_t {
     unsigned char dataAllowed;
     unsigned char contractDetails;
@@ -82,8 +87,7 @@ typedef union extraInfo_t {
 } extraInfo_t;
 
 typedef struct transactionContext_t {
-    uint8_t pathLength;
-    uint32_t bip32Path[MAX_BIP32_PATH];
+    bip32_path_t bip32;
     uint8_t hash[INT256_LENGTH];
     union extraInfo_t extraInfo[MAX_ITEMS];
     uint8_t tokenSet[MAX_ITEMS];
@@ -91,15 +95,13 @@ typedef struct transactionContext_t {
 } transactionContext_t;
 
 typedef struct messageSigningContext_t {
-    uint8_t pathLength;
-    uint32_t bip32Path[MAX_BIP32_PATH];
+    bip32_path_t bip32;
     uint8_t hash[INT256_LENGTH];
     uint32_t remainingLength;
 } messageSigningContext_t;
 
 typedef struct messageSigningContext712_t {
-    uint8_t pathLength;
-    uint32_t bip32Path[MAX_BIP32_PATH];
+    bip32_path_t bip32;
     uint8_t domainHash[32];
     uint8_t messageHash[32];
 } messageSigningContext712_t;
@@ -217,5 +219,6 @@ extern uint32_t eth2WithdrawalIndex;
 #endif
 
 void reset_app_context(void);
+const uint8_t *parseBip32(const uint8_t *, uint16_t *, bip32_path_t *);
 
 #endif  // _SHARED_CONTEXT_H_
diff --git a/src/stark_crypto.c b/src/stark_crypto.c
index 8f33a011a..ca738c930 100644
--- a/src/stark_crypto.c
+++ b/src/stark_crypto.c
@@ -2,10 +2,11 @@
 
 #include "shared_context.h"
 #include "stark_utils.h"
-#include "ui_callbacks.h"
 #include "utils.h"
 #include "ethUtils.h"
 
+extraInfo_t *getKnownToken(uint8_t *contractAddress);
+
 static unsigned char const C_cx_Stark256_n[] = {
     // n: 0x0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f
     0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
diff --git a/src/tokens.c b/src/tokens.c
index b26771ccf..ed5ce27f4 100644
--- a/src/tokens.c
+++ b/src/tokens.c
@@ -212,4 +212,14 @@ const tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR] = {};
 
 const tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN] = {};
 
+const tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK] = {};
+
+const tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER] = {};
+
+const tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC] = {};
+
+const tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA] = {};
+
+const tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK] = {};
+
 #endif
diff --git a/src/tokens.h b/src/tokens.h
index 318edad6a..9da9a2278 100644
--- a/src/tokens.h
+++ b/src/tokens.h
@@ -110,6 +110,11 @@ static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = {
 #define NUM_TOKENS_CUBE             0
 #define NUM_TOKENS_ASTAR            0
 #define NUM_TOKENS_SHIDEN           0
+#define NUM_TOKENS_XDCNETWORK       0
+#define NUM_TOKENS_METER            0
+#define NUM_TOKENS_MULTIVAC         0
+#define NUM_TOKENS_TECRA            0
+#define NUM_TOKENS_APOTHEMNETWORK   0
 
 extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA];
 extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM];
@@ -155,6 +160,11 @@ extern tokenDefinition_t const TOKENS_WETHIO[NUM_TOKENS_WETHIO];
 extern tokenDefinition_t const TOKENS_CUBE[NUM_TOKENS_CUBE];
 extern tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR];
 extern tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN];
+extern tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK];
+extern tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER];
+extern tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC];
+extern tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA];
+extern tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK];
 
 #endif /* HAVE_TOKENS_LIST */
 
diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h
index 2d7ff98e4..1616e3e6d 100644
--- a/src/ui_callbacks.h
+++ b/src/ui_callbacks.h
@@ -10,8 +10,8 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_tx_cancel(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_address_cancel(const bagl_element_t *e);
-unsigned int io_seproxyhal_touch_signMessage_ok(const bagl_element_t *e);
-unsigned int io_seproxyhal_touch_signMessage_cancel(const bagl_element_t *e);
+unsigned int io_seproxyhal_touch_signMessage_ok(void);
+unsigned int io_seproxyhal_touch_signMessage_cancel(void);
 unsigned int io_seproxyhal_touch_data_ok(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_data_cancel(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_signMessage712_v0_ok(const bagl_element_t *e);
@@ -19,8 +19,10 @@ unsigned int io_seproxyhal_touch_signMessage712_v0_cancel(const bagl_element_t *
 unsigned int io_seproxyhal_touch_eth2_address_ok(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_privacy_ok(const bagl_element_t *e);
 unsigned int io_seproxyhal_touch_privacy_cancel(const bagl_element_t *e);
+unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e);
+unsigned int io_seproxyhal_touch_stark_pubkey_ok(const bagl_element_t *e);
+unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e);
 
-void ui_idle(void);
 void ui_warning_contract_data(void);
 
 void io_seproxyhal_send_status(uint32_t sw);
diff --git a/src/utils.c b/src/utils.c
index e6d60e1af..7a5627fd2 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -54,7 +54,7 @@ int local_strchr(char *string, char ch) {
     return -1;
 }
 
-uint64_t u64_from_BE(uint8_t *in, uint8_t size) {
+uint64_t u64_from_BE(const uint8_t *in, uint8_t size) {
     uint8_t i = 0;
     uint64_t res = 0;
 
diff --git a/src/utils.h b/src/utils.h
index 5afabd409..bd523986c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -28,7 +28,7 @@ void convertUint256BE(uint8_t* data, uint32_t length, uint256_t* target);
 
 int local_strchr(char* string, char ch);
 
-uint64_t u64_from_BE(uint8_t* in, uint8_t size);
+uint64_t u64_from_BE(const uint8_t* in, uint8_t size);
 
 bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len);
 
diff --git a/src_bagl/common_ui.c b/src_bagl/common_ui.c
new file mode 100644
index 000000000..e1449f0b3
--- /dev/null
+++ b/src_bagl/common_ui.c
@@ -0,0 +1,73 @@
+#ifdef HAVE_BAGL
+
+#include "common_ui.h"
+#include "ux.h"
+#include "ui_flow.h"
+
+void ui_idle(void) {
+    // reserve a display stack slot if none yet
+    if (G_ux.stack_count == 0) {
+        ux_stack_push();
+    }
+    ux_flow_init(0, ux_idle_flow, NULL);
+}
+
+void ui_warning_contract_data(void) {
+    ux_flow_init(0, ux_warning_contract_data_flow, NULL);
+}
+
+void ui_display_public_eth2(void) {
+    ux_flow_init(0, ux_display_public_eth2_flow, NULL);
+}
+
+void ui_display_privacy_public_key(void) {
+    ux_flow_init(0, ux_display_privacy_public_key_flow, NULL);
+}
+
+void ui_display_privacy_shared_secret(void) {
+    ux_flow_init(0, ux_display_privacy_shared_secret_flow, NULL);
+}
+
+void ui_display_public_key(void) {
+    ux_flow_init(0, ux_display_public_flow, NULL);
+}
+
+void ui_sign_712_v0(void) {
+    ux_flow_init(0, ux_sign_712_v0_flow, NULL);
+}
+
+#ifdef HAVE_STARKWARE
+void ui_display_stark_public(void) {
+    ux_flow_init(0, ux_display_stark_public_flow, NULL);
+}
+void ui_stark_limit_order(void) {
+    ux_flow_init(0, ux_stark_limit_order_flow, NULL);
+}
+
+void ui_stark_unsafe_sign(void) {
+    ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL);
+}
+
+void ui_stark_transfer(bool selfTransfer, bool conditional) {
+    if (selfTransfer) {
+        ux_flow_init(
+            0,
+            (conditional ? ux_stark_self_transfer_conditional_flow : ux_stark_self_transfer_flow),
+            NULL);
+    } else {
+        ux_flow_init(0,
+                     (conditional ? ux_stark_transfer_conditional_flow : ux_stark_transfer_flow),
+                     NULL);
+    }
+}
+#endif  // HAVE_STARKWARE
+
+void ui_confirm_selector(void) {
+    ux_flow_init(0, ux_confirm_selector_flow, NULL);
+}
+
+void ui_confirm_parameter(void) {
+    ux_flow_init(0, ux_confirm_parameter_flow, NULL);
+}
+
+#endif  // HAVE_BAGL
diff --git a/src/ui_flow.c b/src_bagl/ui_flow.c
similarity index 99%
rename from src/ui_flow.c
rename to src_bagl/ui_flow.c
index d6c0a1672..79cedf4fa 100644
--- a/src/ui_flow.c
+++ b/src_bagl/ui_flow.c
@@ -1,5 +1,5 @@
 #include "shared_context.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 void display_settings(const ux_flow_step_t* const start_step);
 void switch_settings_blind_signing(void);
@@ -184,4 +184,4 @@ UX_STEP_CB(
 #endif
 // clang-format on
 
-UX_FLOW(ux_warning_contract_data_flow, &ux_warning_contract_data_step);
\ No newline at end of file
+UX_FLOW(ux_warning_contract_data_flow, &ux_warning_contract_data_step);
diff --git a/src/ui_flow.h b/src_bagl/ui_flow.h
similarity index 97%
rename from src/ui_flow.h
rename to src_bagl/ui_flow.h
index 796e4da68..184036b67 100644
--- a/src/ui_flow.h
+++ b/src_bagl/ui_flow.h
@@ -20,8 +20,6 @@ extern const ux_flow_step_t* const ux_confirm_parameter_flow[];
 
 extern const ux_flow_step_t* const ux_approval_allowance_flow[];
 
-extern const ux_flow_step_t* const ux_sign_flow[];
-
 extern const ux_flow_step_t* const ux_sign_712_v0_flow[];
 
 extern const ux_flow_step_t* const ux_display_public_eth2_flow[];
@@ -30,6 +28,8 @@ extern const ux_flow_step_t* const ux_display_privacy_public_key_flow[];
 
 extern const ux_flow_step_t* const ux_display_privacy_shared_secret_flow[];
 
+extern const ux_flow_step_t* ux_approval_tx_flow[15];
+
 #ifdef HAVE_STARKWARE
 
 extern const ux_flow_step_t* const ux_display_stark_public_flow[];
diff --git a/src_features/erc20_approval/ui_flow_erc20_approval.c b/src_bagl/ui_flow_erc20_approval.c
similarity index 100%
rename from src_features/erc20_approval/ui_flow_erc20_approval.c
rename to src_bagl/ui_flow_erc20_approval.c
diff --git a/src_features/getEth2PublicKey/ui_flow_getEth2PublicKey.c b/src_bagl/ui_flow_getEth2PublicKey.c
similarity index 100%
rename from src_features/getEth2PublicKey/ui_flow_getEth2PublicKey.c
rename to src_bagl/ui_flow_getEth2PublicKey.c
diff --git a/src_features/getPublicKey/ui_flow_getPublicKey.c b/src_bagl/ui_flow_getPublicKey.c
similarity index 100%
rename from src_features/getPublicKey/ui_flow_getPublicKey.c
rename to src_bagl/ui_flow_getPublicKey.c
diff --git a/src_features/performPrivacyOperation/ui_flow_performPrivacyOperation.c b/src_bagl/ui_flow_performPrivacyOperation.c
similarity index 100%
rename from src_features/performPrivacyOperation/ui_flow_performPrivacyOperation.c
rename to src_bagl/ui_flow_performPrivacyOperation.c
diff --git a/src_bagl/ui_flow_signMessage.c b/src_bagl/ui_flow_signMessage.c
new file mode 100644
index 000000000..9b97d574b
--- /dev/null
+++ b/src_bagl/ui_flow_signMessage.c
@@ -0,0 +1,128 @@
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "common_ui.h"
+#include "sign_message.h"
+
+typedef enum { UI_191_POS_REVIEW, UI_191_POS_QUESTION, UI_191_POS_END } e_ui_191_position;
+
+static uint8_t ui_pos;
+
+static void dummy_pre_cb(void) {
+    if (ui_pos == UI_191_POS_REVIEW) {
+        question_switcher();
+    } else {
+        ux_flow_prev();
+        ui_pos = UI_191_POS_REVIEW;
+    }
+}
+
+static void dummy_post_cb(void) {
+    if (ui_pos == UI_191_POS_QUESTION) {
+        continue_displaying_message();
+    } else  // UI_191_END
+    {
+        ui_191_switch_to_message_end();
+    }
+}
+
+// clang-format off
+UX_STEP_NOCB(
+    ux_191_step_review,
+    pnn,
+    {
+      &C_icon_certificate,
+      "Sign",
+      "message",
+    });
+UX_STEP_NOCB(
+    ux_191_step_message,
+    bnnn_paging,
+    {
+      .title = "Message",
+      .text = strings.tmp.tmp,
+    });
+UX_STEP_INIT(
+    ux_191_step_dummy_pre,
+    NULL,
+    NULL,
+    {
+      dummy_pre_cb();
+    });
+UX_STEP_CB(
+    ux_191_step_theres_more,
+#ifdef TARGET_NANOS
+    nn,
+#else
+    nnn,
+#endif
+    skip_rest_of_message(),
+    {
+#ifndef TARGET_NANOS
+      "Press right to",
+      "continue message",
+#else
+      "Press right to read",
+#endif
+      "Double-press to skip"
+    });
+UX_STEP_INIT(
+    ux_191_step_dummy_post,
+    NULL,
+    NULL,
+    {
+      dummy_post_cb();
+    });
+UX_STEP_CB(
+    ux_191_step_sign,
+    pbb,
+    io_seproxyhal_touch_signMessage_ok(),
+    {
+      &C_icon_validate_14,
+      "Sign",
+      "message",
+    });
+UX_STEP_CB(
+    ux_191_step_cancel,
+    pbb,
+    io_seproxyhal_touch_signMessage_cancel(),
+    {
+      &C_icon_crossmark,
+      "Cancel",
+      "signature",
+    });
+// clang-format on
+
+UX_FLOW(ux_191_flow,
+        &ux_191_step_review,
+        &ux_191_step_message,
+        &ux_191_step_dummy_pre,
+        &ux_191_step_theres_more,
+        &ux_191_step_dummy_post,
+        &ux_191_step_sign,
+        &ux_191_step_cancel);
+
+void ui_191_start(void) {
+    ux_flow_init(0, ux_191_flow, NULL);
+    ui_pos = UI_191_POS_REVIEW;
+}
+
+void ui_191_switch_to_message(void) {
+    ux_flow_init(0, ux_191_flow, &ux_191_step_message);
+    ui_pos = UI_191_POS_REVIEW;
+}
+
+void ui_191_switch_to_message_end(void) {
+    // Force it to a value that will make it automatically do a prev()
+    ui_pos = UI_191_POS_QUESTION;
+    ux_flow_init(0, ux_191_flow, &ux_191_step_dummy_pre);
+}
+
+void ui_191_switch_to_sign(void) {
+    ux_flow_init(0, ux_191_flow, &ux_191_step_sign);
+    ui_pos = UI_191_POS_END;
+}
+
+void ui_191_switch_to_question(void) {
+    ux_flow_init(0, ux_191_flow, &ux_191_step_theres_more);
+    ui_pos = UI_191_POS_QUESTION;
+}
diff --git a/src_features/signMessageEIP712/ui_flow_signMessage712.c b/src_bagl/ui_flow_signMessage712.c
similarity index 100%
rename from src_features/signMessageEIP712/ui_flow_signMessage712.c
rename to src_bagl/ui_flow_signMessage712.c
diff --git a/src_features/signTx/ui_flow_signTx.c b/src_bagl/ui_flow_signTx.c
similarity index 99%
rename from src_features/signTx/ui_flow_signTx.c
rename to src_bagl/ui_flow_signTx.c
index 8f6a974d4..6d05d6d04 100644
--- a/src_features/signTx/ui_flow_signTx.c
+++ b/src_bagl/ui_flow_signTx.c
@@ -6,6 +6,7 @@
 #include "network.h"
 #include "eth_plugin_handler.h"
 #include "ui_plugin.h"
+#include "common_ui.h"
 
 // clang-format off
 UX_STEP_NOCB(
diff --git a/src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c b/src_bagl/ui_flow_stark_getPublicKey.c
similarity index 92%
rename from src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c
rename to src_bagl/ui_flow_stark_getPublicKey.c
index 7f7b374d9..958874fc2 100644
--- a/src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c
+++ b/src_bagl/ui_flow_stark_getPublicKey.c
@@ -3,8 +3,6 @@
 #include "shared_context.h"
 #include "ui_callbacks.h"
 
-unsigned int io_seproxyhal_touch_stark_pubkey_ok(const bagl_element_t *e);
-
 // clang-format off
 UX_STEP_NOCB(
     ux_display_stark_public_flow_1_step,
diff --git a/src_features/stark_sign/ui_flow_stark_sign.c b/src_bagl/ui_flow_stark_sign.c
similarity index 98%
rename from src_features/stark_sign/ui_flow_stark_sign.c
rename to src_bagl/ui_flow_stark_sign.c
index 23c931926..df3c6a1e8 100644
--- a/src_features/stark_sign/ui_flow_stark_sign.c
+++ b/src_bagl/ui_flow_stark_sign.c
@@ -4,8 +4,6 @@
 #include "ui_callbacks.h"
 #include "ethUtils.h"
 
-unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e);
-
 void stark_sign_display_master_account() {
     snprintf(strings.tmp.tmp,
              sizeof(strings.tmp.tmp),
diff --git a/src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c b/src_bagl/ui_flow_stark_unsafe_sign.c
similarity index 100%
rename from src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c
rename to src_bagl/ui_flow_stark_unsafe_sign.c
diff --git a/src_features/signTx/ui_plugin.c b/src_bagl/ui_plugin.c
similarity index 100%
rename from src_features/signTx/ui_plugin.c
rename to src_bagl/ui_plugin.c
diff --git a/src_features/signTx/ui_plugin.h b/src_bagl/ui_plugin.h
similarity index 100%
rename from src_features/signTx/ui_plugin.h
rename to src_bagl/ui_plugin.h
diff --git a/src_common/ethUstream.c b/src_common/ethUstream.c
index 7f6bc658f..81e607dc3 100644
--- a/src_common/ethUstream.c
+++ b/src_common/ethUstream.c
@@ -296,6 +296,12 @@ static void processV(txContext_t *context) {
         PRINTF("Invalid type for RLP_V\n");
         THROW(EXCEPTION);
     }
+
+    if (context->currentFieldLength > sizeof(context->content->v)) {
+        PRINTF("Invalid length for RLP_V\n");
+        THROW(EXCEPTION);
+    }
+
     if (context->currentFieldPos < context->currentFieldLength) {
         uint32_t copySize =
             MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos);
@@ -586,7 +592,7 @@ static parserStatus_e processTxInternal(txContext_t *context) {
 }
 
 parserStatus_e processTx(txContext_t *context,
-                         uint8_t *buffer,
+                         const uint8_t *buffer,
                          uint32_t length,
                          uint32_t processingFlags) {
     parserStatus_e result;
@@ -596,7 +602,7 @@ parserStatus_e processTx(txContext_t *context,
             context->commandLength = length;
             context->processingFlags = processingFlags;
             result = processTxInternal(context);
-            PRINTF("result: %d\n");
+            PRINTF("result: %d\n", result);
         }
         CATCH_OTHER(e) {
             result = USTREAM_FAULT;
diff --git a/src_common/ethUstream.h b/src_common/ethUstream.h
index f63dd6517..4229d4083 100644
--- a/src_common/ethUstream.h
+++ b/src_common/ethUstream.h
@@ -142,7 +142,7 @@ typedef struct txContext_t {
     uint32_t dataLength;
     uint8_t rlpBuffer[5];
     uint32_t rlpBufferPos;
-    uint8_t *workBuffer;
+    const uint8_t *workBuffer;
     uint32_t commandLength;
     uint32_t processingFlags;
     ustreamProcess_t customProcessor;
@@ -157,7 +157,7 @@ void initTx(txContext_t *context,
             ustreamProcess_t customProcessor,
             void *extra);
 parserStatus_e processTx(txContext_t *context,
-                         uint8_t *buffer,
+                         const uint8_t *buffer,
                          uint32_t length,
                          uint32_t processingFlags);
 parserStatus_e continueTx(txContext_t *context);
diff --git a/src_common/network.c b/src_common/network.c
index 2d090b90c..5bd29f724 100644
--- a/src_common/network.c
+++ b/src_common/network.c
@@ -27,7 +27,28 @@ const network_info_t NETWORK_MAPPING[] = {
     {.chain_id = 11297108109, .name = "Palm Network", .ticker = "PALM "},
     {.chain_id = 1818, .name = "Cube", .ticker = "CUBE "},
     {.chain_id = 336, .name = "Shiden", .ticker = "SDN "},
-    {.chain_id = 592, .name = "Astar", .ticker = "ASTR "}};
+    {.chain_id = 592, .name = "Astar", .ticker = "ASTR "},
+    {.chain_id = 50, .name = "XDC", .ticker = "XDC "},
+    {.chain_id = 82, .name = "Meter", .ticker = "MTR "},
+    {.chain_id = 62621, .name = "Multivac", .ticker = "MTV "},
+    {.chain_id = 20531812, .name = "Tecra", .ticker = "TCR "},
+    {.chain_id = 20531811, .name = "TecraTestnet", .ticker = "TCR "},
+    {.chain_id = 51, .name = "Apothemnetwork", .ticker = "XDC "},
+    {.chain_id = 199, .name = "BTTC", .ticker = "BTT "},
+    {.chain_id = 1030, .name = "Conflux", .ticker = "CFX "},
+    {.chain_id = 61, .name = "Ethereum Classic", .ticker = "ETC "},
+    {.chain_id = 246, .name = "EnergyWebChain", .ticker = "EWC "},
+    {.chain_id = 14, .name = "Flare", .ticker = "FLR "},
+    {.chain_id = 16, .name = "Flare Coston", .ticker = "FLR "},
+    {.chain_id = 24, .name = "KardiaChain", .ticker = "KAI "},
+    {.chain_id = 1284, .name = "Moonbeam", .ticker = "GLMR "},
+    {.chain_id = 1285, .name = "Moonriver", .ticker = "MOVR "},
+    {.chain_id = 66, .name = "OKXChain", .ticker = "OKT "},
+    {.chain_id = 99, .name = "POA", .ticker = "POA "},
+    {.chain_id = 7341, .name = "Shyft", .ticker = "SHFT "},
+    {.chain_id = 19, .name = "Songbird", .ticker = "SGB "},
+    {.chain_id = 73799, .name = "Volta", .ticker = "VOLTA "},
+    {.chain_id = 25, .name = "Cronos", .ticker = "CRO "}};
 
 uint64_t get_chain_id(void) {
     uint64_t chain_id = 0;
diff --git a/src_common/network.h b/src_common/network.h
index 8a4513af5..ade31523e 100644
--- a/src_common/network.h
+++ b/src_common/network.h
@@ -8,8 +8,8 @@
 #define MAX_NETWORK_TICKER_LEN 8
 
 typedef struct network_info_s {
-    const char name[NETWORK_STRING_MAX_SIZE];
-    const char ticker[MAX_NETWORK_TICKER_LEN];
+    const char *name;
+    const char *ticker;
     uint64_t chain_id;
 } network_info_t;
 
diff --git a/src_common/uint256.c b/src_common/uint256.c
index 92b4d1fcd..22b738edb 100644
--- a/src_common/uint256.c
+++ b/src_common/uint256.c
@@ -476,6 +476,11 @@ bool tostring256(uint256_t *number, uint32_t baseParam, char *out, uint32_t outL
         divmod256(&rDiv, &base, &rDiv, &rMod);
         out[offset++] = HEXDIGITS[(uint8_t) LOWER(LOWER(rMod))];
     } while (!zero256(&rDiv));
+
+    if (offset > (outLength - 1)) {
+        return false;
+    }
+
     out[offset] = '\0';
     reverseString(out, offset);
     return true;
diff --git a/src_features/getAppConfiguration/cmd_getAppConfiguration.c b/src_features/getAppConfiguration/cmd_getAppConfiguration.c
index c67b7f329..cac55448c 100644
--- a/src_features/getAppConfiguration/cmd_getAppConfiguration.c
+++ b/src_features/getAppConfiguration/cmd_getAppConfiguration.c
@@ -1,11 +1,9 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 
-#include "ui_flow.h"
-
 void handleGetAppConfiguration(uint8_t p1,
                                uint8_t p2,
-                               uint8_t *workBuffer,
+                               const uint8_t *workBuffer,
                                uint16_t dataLength,
                                unsigned int *flags,
                                unsigned int *tx) {
diff --git a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
index 33ca89598..b88dada32 100644
--- a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
+++ b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
@@ -3,8 +3,9 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 
-#include "ui_flow.h"
 #include "feature_getEth2PublicKey.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 static const uint8_t BLS12_381_FIELD_MODULUS[] = {
     0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7,
@@ -42,33 +43,29 @@ void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out
 
 void handleGetEth2PublicKey(uint8_t p1,
                             uint8_t p2,
-                            uint8_t *dataBuffer,
+                            const uint8_t *dataBuffer,
                             uint16_t dataLength,
                             unsigned int *flags,
                             unsigned int *tx) {
-    UNUSED(dataLength);
-    uint32_t bip32Path[MAX_BIP32_PATH];
-    uint32_t i;
-    uint8_t bip32PathLength = *(dataBuffer++);
+    bip32_path_t bip32;
 
     if (!called_from_swap) {
         reset_app_context();
     }
-    if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
-    }
     if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
         THROW(0x6B00);
     }
     if (p2 != 0) {
         THROW(0x6B00);
     }
-    for (i = 0; i < bip32PathLength; i++) {
-        bip32Path[i] = U4BE(dataBuffer, 0);
-        dataBuffer += 4;
+
+    dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32);
+
+    if (dataBuffer == NULL) {
+        THROW(0x6a80);
     }
-    getEth2PublicKey(bip32Path, bip32PathLength, tmpCtx.publicKeyContext.publicKey.W);
+
+    getEth2PublicKey(bip32.path, bip32.length, tmpCtx.publicKeyContext.publicKey.W);
 
 #ifndef NO_CONSENT
     if (p1 == P1_NON_CONFIRM)
@@ -79,7 +76,7 @@ void handleGetEth2PublicKey(uint8_t p1,
     }
 #ifndef NO_CONSENT
     else {
-        ux_flow_init(0, ux_display_public_eth2_flow, NULL);
+        ui_display_public_eth2();
 
         *flags |= IO_ASYNCH_REPLY;
     }
diff --git a/src_features/getEth2PublicKey/ui_common_getEth2PublicKey.c b/src_features/getEth2PublicKey/ui_common_getEth2PublicKey.c
index ca10fc3f5..77b38c0e3 100644
--- a/src_features/getEth2PublicKey/ui_common_getEth2PublicKey.c
+++ b/src_features/getEth2PublicKey/ui_common_getEth2PublicKey.c
@@ -2,7 +2,7 @@
 
 #include "shared_context.h"
 #include "feature_getEth2PublicKey.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_eth2_address_ok(__attribute__((unused)) const bagl_element_t *e) {
     uint32_t tx = set_result_get_eth2_publicKey();
diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c
index 59c9fb8d9..3c25640eb 100644
--- a/src_features/getPublicKey/cmd_getPublicKey.c
+++ b/src_features/getPublicKey/cmd_getPublicKey.c
@@ -1,45 +1,44 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 
-#include "ui_flow.h"
 #include "feature_getPublicKey.h"
 #include "ethUtils.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 void handleGetPublicKey(uint8_t p1,
                         uint8_t p2,
-                        uint8_t *dataBuffer,
+                        const uint8_t *dataBuffer,
                         uint16_t dataLength,
                         unsigned int *flags,
                         unsigned int *tx) {
-    UNUSED(dataLength);
     uint8_t privateKeyData[INT256_LENGTH];
-    uint32_t bip32Path[MAX_BIP32_PATH];
-    uint32_t i;
-    uint8_t bip32PathLength = *(dataBuffer++);
+    bip32_path_t bip32;
     cx_ecfp_private_key_t privateKey;
+
     if (!called_from_swap) {
         reset_app_context();
     }
-    if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
-    }
+
     if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
         THROW(0x6B00);
     }
     if ((p2 != P2_CHAINCODE) && (p2 != P2_NO_CHAINCODE)) {
         THROW(0x6B00);
     }
-    for (i = 0; i < bip32PathLength; i++) {
-        bip32Path[i] = U4BE(dataBuffer, 0);
-        dataBuffer += 4;
+
+    dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32);
+
+    if (dataBuffer == NULL) {
+        THROW(0x6a80);
     }
+
     tmpCtx.publicKeyContext.getChaincode = (p2 == P2_CHAINCODE);
     io_seproxyhal_io_heartbeat();
     os_perso_derive_node_bip32(
         CX_CURVE_256K1,
-        bip32Path,
-        bip32PathLength,
+        bip32.path,
+        bip32.length,
         privateKeyData,
         (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL));
     cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
@@ -66,7 +65,7 @@ void handleGetPublicKey(uint8_t p1,
                  "0x%.*s",
                  40,
                  tmpCtx.publicKeyContext.address);
-        ux_flow_init(0, ux_display_public_flow, NULL);
+        ui_display_public_key();
 
         *flags |= IO_ASYNCH_REPLY;
     }
diff --git a/src_features/getPublicKey/ui_common_getPublicKey.c b/src_features/getPublicKey/ui_common_getPublicKey.c
index c7bd3a3d0..d38724a36 100644
--- a/src_features/getPublicKey/ui_common_getPublicKey.c
+++ b/src_features/getPublicKey/ui_common_getPublicKey.c
@@ -1,6 +1,6 @@
 #include "shared_context.h"
 #include "feature_getPublicKey.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_address_ok(__attribute__((unused)) const bagl_element_t *e) {
     uint32_t tx = set_result_get_publicKey();
diff --git a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
index 9bd58020e..da9d98681 100644
--- a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
+++ b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
@@ -2,8 +2,8 @@
 #include "apdu_constants.h"
 #include "ethUtils.h"
 
-#include "ui_flow.h"
 #include "feature_performPrivacyOperation.h"
+#include "common_ui.h"
 
 #define P2_PUBLIC_ENCRYPTION_KEY 0x00
 #define P2_SHARED_SECRET         0x01
@@ -25,43 +25,39 @@ void decodeScalar(const uint8_t *scalarIn, uint8_t *scalarOut) {
 
 void handlePerformPrivacyOperation(uint8_t p1,
                                    uint8_t p2,
-                                   uint8_t *dataBuffer,
+                                   const uint8_t *dataBuffer,
                                    uint16_t dataLength,
                                    unsigned int *flags,
                                    unsigned int *tx) {
-    UNUSED(dataLength);
     uint8_t privateKeyData[INT256_LENGTH];
     uint8_t privateKeyDataSwapped[INT256_LENGTH];
-    uint32_t bip32Path[MAX_BIP32_PATH];
-    uint8_t bip32PathLength = *(dataBuffer++);
+    bip32_path_t bip32;
     cx_err_t status = CX_OK;
-    if (p2 == P2_PUBLIC_ENCRYPTION_KEY) {
-        if (dataLength < 1 + 4 * bip32PathLength) {
-            THROW(0x6700);
-        }
-    } else if (p2 == P2_SHARED_SECRET) {
-        if (dataLength < 1 + 4 * bip32PathLength + 32) {
-            THROW(0x6700);
-        }
-    } else {
+
+    if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
         THROW(0x6B00);
     }
-    cx_ecfp_private_key_t privateKey;
-    if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
+
+    if ((p2 != P2_PUBLIC_ENCRYPTION_KEY) && (p2 != P2_SHARED_SECRET)) {
+        THROW(0x6700);
     }
-    if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
-        THROW(0x6B00);
+
+    dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32);
+
+    if (dataBuffer == NULL) {
+        THROW(0x6a80);
     }
-    for (uint8_t i = 0; i < bip32PathLength; i++) {
-        bip32Path[i] = U4BE(dataBuffer, 0);
-        dataBuffer += 4;
+
+    if ((p2 == P2_SHARED_SECRET) && (dataLength < 32)) {
+        THROW(0x6700);
     }
+
+    cx_ecfp_private_key_t privateKey;
+
     os_perso_derive_node_bip32(
         CX_CURVE_256K1,
-        bip32Path,
-        bip32PathLength,
+        bip32.path,
+        bip32.length,
         privateKeyData,
         (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL));
     cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
@@ -112,9 +108,9 @@ void handlePerformPrivacyOperation(uint8_t p1,
                  32,
                  privateKeyData);
         if (p2 == P2_PUBLIC_ENCRYPTION_KEY) {
-            ux_flow_init(0, ux_display_privacy_public_key_flow, NULL);
+            ui_display_privacy_public_key();
         } else {
-            ux_flow_init(0, ux_display_privacy_shared_secret_flow, NULL);
+            ui_display_privacy_shared_secret();
         }
 
         *flags |= IO_ASYNCH_REPLY;
diff --git a/src_features/performPrivacyOperation/ui_common_performPrivacyOperation.c b/src_features/performPrivacyOperation/ui_common_performPrivacyOperation.c
index ac045f208..a2cb1c3d7 100644
--- a/src_features/performPrivacyOperation/ui_common_performPrivacyOperation.c
+++ b/src_features/performPrivacyOperation/ui_common_performPrivacyOperation.c
@@ -1,6 +1,6 @@
 #include "shared_context.h"
 #include "feature_getPublicKey.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 #include "feature_performPrivacyOperation.h"
 
 unsigned int io_seproxyhal_touch_privacy_ok(__attribute__((unused)) const bagl_element_t *e) {
diff --git a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c
index 4f09b1fab..dc231171d 100644
--- a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c
+++ b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c
@@ -1,7 +1,8 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "tokens.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 #ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
 
@@ -101,7 +102,7 @@ void handleProvideErc20TokenInformation(uint8_t p1,
 
 void handleProvideErc20TokenInformation(uint8_t p1,
                                         uint8_t p2,
-                                        uint8_t *workBuffer,
+                                        const uint8_t *workBuffer,
                                         uint16_t dataLength,
                                         unsigned int *flags,
                                         __attribute__((unused)) unsigned int *tx) {
diff --git a/src_features/provideNFTInformation/cmd_provideNFTInfo.c b/src_features/provideNFTInformation/cmd_provideNFTInfo.c
index e7fea89e8..4469061c6 100644
--- a/src_features/provideNFTInformation/cmd_provideNFTInfo.c
+++ b/src_features/provideNFTInformation/cmd_provideNFTInfo.c
@@ -2,9 +2,10 @@
 
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "tokens.h"
 #include "utils.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 #define TYPE_SIZE        1
 #define VERSION_SIZE     1
@@ -53,7 +54,7 @@ typedef bool verificationAlgo(const cx_ecfp_public_key_t *,
 
 void handleProvideNFTInformation(uint8_t p1,
                                  uint8_t p2,
-                                 uint8_t *workBuffer,
+                                 const uint8_t *workBuffer,
                                  uint16_t dataLength,
                                  unsigned int *flags,
                                  unsigned int *tx) {
@@ -218,7 +219,7 @@ void handleProvideNFTInformation(uint8_t p1,
                         hashId,
                         hash,
                         sizeof(hash),
-                        workBuffer + offset,
+                        (uint8_t *) workBuffer + offset,
                         signatureLen)) {
 #ifndef HAVE_BYPASS_SIGNATURES
         PRINTF("Invalid NFT signature\n");
diff --git a/src_features/setEth2WithdrawalIndex/cmd_setEth2WithdrawalIndex.c b/src_features/setEth2WithdrawalIndex/cmd_setEth2WithdrawalIndex.c
index d2338ef35..a7f6f72b6 100644
--- a/src_features/setEth2WithdrawalIndex/cmd_setEth2WithdrawalIndex.c
+++ b/src_features/setEth2WithdrawalIndex/cmd_setEth2WithdrawalIndex.c
@@ -5,7 +5,7 @@
 
 void handleSetEth2WithdrawalIndex(uint8_t p1,
                                   uint8_t p2,
-                                  uint8_t *dataBuffer,
+                                  const uint8_t *dataBuffer,
                                   uint16_t dataLength,
                                   __attribute__((unused)) unsigned int *flags,
                                   __attribute__((unused)) unsigned int *tx) {
diff --git a/src_features/setExternalPlugin/cmd_setExternalPlugin.c b/src_features/setExternalPlugin/cmd_setExternalPlugin.c
index 672bfaac6..20506f942 100644
--- a/src_features/setExternalPlugin/cmd_setExternalPlugin.c
+++ b/src_features/setExternalPlugin/cmd_setExternalPlugin.c
@@ -1,13 +1,14 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "tokens.h"
 #include "eth_plugin_interface.h"
 #include "eth_plugin_internal.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 void handleSetExternalPlugin(uint8_t p1,
                              uint8_t p2,
-                             uint8_t *workBuffer,
+                             const uint8_t *workBuffer,
                              uint16_t dataLength,
                              unsigned int *flags,
                              unsigned int *tx) {
diff --git a/src_features/setPlugin/cmd_setPlugin.c b/src_features/setPlugin/cmd_setPlugin.c
index 58ad8bfb9..3cc0c4963 100644
--- a/src_features/setPlugin/cmd_setPlugin.c
+++ b/src_features/setPlugin/cmd_setPlugin.c
@@ -1,10 +1,11 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "tokens.h"
 #include "eth_plugin_interface.h"
 #include "eth_plugin_internal.h"
 #include "utils.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 // Supported internal plugins
 #define ERC721_STR  "ERC721"
@@ -86,7 +87,7 @@ static pluginType_t getPluginType(char *pluginName, uint8_t pluginNameLength) {
 
 void handleSetPlugin(uint8_t p1,
                      uint8_t p2,
-                     uint8_t *workBuffer,
+                     const uint8_t *workBuffer,
                      uint16_t dataLength,
                      unsigned int *flags,
                      unsigned int *tx) {
@@ -248,7 +249,7 @@ void handleSetPlugin(uint8_t p1,
                         hashId,
                         hash,
                         sizeof(hash),
-                        workBuffer + offset,
+                        (unsigned char *) (workBuffer + offset),
                         signatureLen)) {
 #ifndef HAVE_BYPASS_SIGNATURES
         PRINTF("Invalid NFT signature\n");
diff --git a/src_features/signMessage/cmd_signMessage.c b/src_features/signMessage/cmd_signMessage.c
index 7ea12db54..9cfd4d6cb 100644
--- a/src_features/signMessage/cmd_signMessage.c
+++ b/src_features/signMessage/cmd_signMessage.c
@@ -1,212 +1,284 @@
 #include <stdbool.h>
-#include "shared_context.h"
+#include <ctype.h>
+#include <string.h>
 #include "apdu_constants.h"
-#include "utils.h"
-#include "ui_flow.h"
+#include "sign_message.h"
+#include "common_ui.h"
+
+static uint8_t processed_size;
+static struct {
+    sign_message_state sign_state : 1;
+    bool ui_started : 1;
+} states;
 
 static const char SIGN_MAGIC[] =
     "\x19"
     "Ethereum Signed Message:\n";
 
 /**
- * Check if a given character is a "special" displayable ASCII character
+ * Send a response APDU with the given Status Word
  *
- * @param[in] c character we're checking
- * @return wether the character is special or not
+ * @param[in] sw status word
  */
-static inline bool is_char_special(char c) {
-    return ((c >= '\b') && (c <= '\r'));
+static void apdu_reply(uint16_t sw) {
+    G_io_apdu_buffer[0] = (sw >> 8) & 0xff;
+    G_io_apdu_buffer[1] = sw & 0xff;
+    io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
 }
 
 /**
- * Check if a given data is made of ASCII characters
+ * Get unprocessed data from last received APDU
  *
- * @param[in] data the input data
- * @param[in] the length of the input data
- * @return wether the data is fully ASCII or not
+ * @return pointer to data in APDU buffer
  */
-static bool is_data_ascii(const uint8_t *const data, size_t length) {
-    for (uint8_t idx = 0; idx < length; ++idx) {
-        if (!is_char_special(data[idx]) && ((data[idx] < 0x20) || (data[idx] > 0x7e))) {
-            return false;
-        }
-    }
-    return true;
+static const uint8_t *unprocessed_data(void) {
+    return &G_io_apdu_buffer[OFFSET_CDATA] + processed_size;
 }
 
 /**
- * Initialize value string that will be displayed in the UX STEP
+ * Get size of unprocessed data from last received APDU
  *
- * @param[in] if the value is ASCII
+ * @return size of data in bytes
  */
-static void init_value_str(bool is_ascii) {
-    if (is_ascii) {
-        strings.tmp.tmp[0] = '\0';  // init string as empty
-    } else {
-        strcpy(strings.tmp.tmp, "0x");  // will display the hex bytes instead
-    }
+static size_t unprocessed_length(void) {
+    return G_io_apdu_buffer[OFFSET_LC] - processed_size;
 }
 
 /**
- * @return Whether the currently stored data is initialized as ASCII or not
+ * Get used space from UI buffer
+ *
+ * @return size in bytes
  */
-static bool is_value_str_ascii() {
-    return (memcmp(strings.tmp.tmp, "0x", 2) != 0);
+static size_t ui_buffer_length(void) {
+    return strlen(UI_191_BUFFER);
 }
 
 /**
- * Update the global UI string variable by formatting & appending the new data to it
+ * Get remaining space from UI buffer
  *
- * @param[in] data the input data
- * @param[in] length the data length
- * @param[in] is_ascii wether the data is ASCII or not
+ * @return size in bytes
  */
-static void feed_value_str(const uint8_t *const data, size_t length, bool is_ascii) {
-    uint16_t value_strlen = strlen(strings.tmp.tmp);
-
-    if ((value_strlen + 1) < sizeof(strings.tmp.tmp)) {
-        if (is_ascii) {
-            uint8_t src_idx = 0;
-            uint16_t dst_idx = value_strlen;
-            bool prev_is_special = false;
-
-            while ((src_idx < length) && (dst_idx < sizeof(strings.tmp.tmp))) {
-                if (prev_is_special) {
-                    if (!is_char_special(data[src_idx])) {
-                        prev_is_special = false;
-                    }
-                } else {
-                    if (is_char_special(data[src_idx])) {
-                        prev_is_special = true;
-                        strings.tmp.tmp[dst_idx] = ' ';
-                        dst_idx += 1;
-                    }
-                }
-                if (!is_char_special(data[src_idx])) {
-                    strings.tmp.tmp[dst_idx] = data[src_idx];
-                    dst_idx += 1;
-                }
-                src_idx += 1;
-            }
-
-            if (dst_idx < sizeof(strings.tmp.tmp)) {
-                strings.tmp.tmp[dst_idx] = '\0';
-            } else {
-                const char marker[] = "...";
-
-                memcpy(strings.tmp.tmp + sizeof(strings.tmp.tmp) - sizeof(marker),
-                       marker,
-                       sizeof(marker));
-            }
-        } else {
-            // truncate to strings.tmp.tmp 's size
-            length = MIN(length, (sizeof(strings.tmp.tmp) - value_strlen) / 2);
-            for (size_t i = 0; i < length; i++) {
-                snprintf(strings.tmp.tmp + value_strlen + 2 * i,
-                         sizeof(strings.tmp.tmp) - value_strlen - 2 * i,
-                         "%02X",
-                         data[i]);
-            }
-        }
-    }
+static size_t remaining_ui_buffer_length(void) {
+    // -1 for the ending NULL byte
+    return (sizeof(UI_191_BUFFER) - 1) - ui_buffer_length();
 }
 
-void handleSignPersonalMessage(uint8_t p1,
-                               uint8_t p2,
-                               uint8_t *workBuffer,
-                               uint16_t dataLength,
-                               unsigned int *flags,
-                               unsigned int *tx) {
-    UNUSED(tx);
-    uint8_t hashMessage[INT256_LENGTH];
-    if (p1 == P1_FIRST) {
-        char tmp[11] = {0};
-        uint32_t i;
-        if (dataLength < 1) {
-            PRINTF("Invalid data\n");
-            THROW(0x6a80);
-        }
-        if (appState != APP_STATE_IDLE) {
-            reset_app_context();
-        }
-        appState = APP_STATE_SIGNING_MESSAGE;
-
-        tmpCtx.messageSigningContext.pathLength = workBuffer[0];
-        if ((tmpCtx.messageSigningContext.pathLength < 0x01) ||
-            (tmpCtx.messageSigningContext.pathLength > MAX_BIP32_PATH)) {
-            PRINTF("Invalid path\n");
-            THROW(0x6a80);
-        }
-        workBuffer++;
-        dataLength--;
-        for (i = 0; i < tmpCtx.messageSigningContext.pathLength; i++) {
-            if (dataLength < sizeof(uint32_t)) {
-                PRINTF("Invalid data\n");
-                THROW(0x6a80);
-            }
-            tmpCtx.messageSigningContext.bip32Path[i] = U4BE(workBuffer, 0);
-            workBuffer += sizeof(uint32_t);
-            dataLength -= sizeof(uint32_t);
-        }
-        if (dataLength < sizeof(uint32_t)) {
-            PRINTF("Invalid data\n");
-            THROW(0x6a80);
-        }
-        tmpCtx.messageSigningContext.remainingLength = U4BE(workBuffer, 0);
-        workBuffer += sizeof(uint32_t);
-        dataLength -= sizeof(uint32_t);
-        // Initialize message header + length
-        cx_keccak_init(&global_sha3, 256);
-        cx_hash((cx_hash_t *) &global_sha3,
-                0,
-                (uint8_t *) SIGN_MAGIC,
-                sizeof(SIGN_MAGIC) - 1,
-                NULL,
-                0);
-        snprintf(tmp, sizeof(tmp), "%u", tmpCtx.messageSigningContext.remainingLength);
-        cx_hash((cx_hash_t *) &global_sha3, 0, (uint8_t *) tmp, strlen(tmp), NULL, 0);
-        cx_sha256_init(&tmpContent.sha2);
+/**
+ * Get free space from UI buffer
+ *
+ * @return pointer to the free space
+ */
+static char *remaining_ui_buffer(void) {
+    return &UI_191_BUFFER[ui_buffer_length()];
+}
 
-        init_value_str(is_data_ascii(workBuffer, dataLength));
+/**
+ * Reset the UI buffer
+ *
+ * Simply sets its first byte to a NULL character
+ */
+static void reset_ui_buffer(void) {
+    UI_191_BUFFER[0] = '\0';
+}
 
-    } else if (p1 != P1_MORE) {
-        THROW(0x6B00);
-    }
-    if (p2 != 0) {
-        THROW(0x6B00);
+/**
+ * Handle the data specific to the first APDU of an EIP-191 signature
+ *
+ * @param[in] data the APDU payload
+ * @param[in] length the payload size
+ * @return pointer to the start of the start of the message; \ref NULL if it failed
+ */
+static const uint8_t *first_apdu_data(const uint8_t *data, uint16_t *length) {
+    if (appState != APP_STATE_IDLE) {
+        reset_app_context();
     }
-    if ((p1 == P1_MORE) && (appState != APP_STATE_SIGNING_MESSAGE)) {
-        PRINTF("Signature not initialized\n");
-        THROW(0x6985);
+    appState = APP_STATE_SIGNING_MESSAGE;
+    data = parseBip32(data, length, &tmpCtx.messageSigningContext.bip32);
+    if (data == NULL) {
+        apdu_reply(0x6a80);
+        return NULL;
     }
-    if (dataLength > tmpCtx.messageSigningContext.remainingLength) {
-        THROW(0x6A80);
+
+    if (*length < sizeof(uint32_t)) {
+        PRINTF("Invalid data\n");
+        apdu_reply(0x6a80);
+        return NULL;
     }
 
-    cx_hash((cx_hash_t *) &global_sha3, 0, workBuffer, dataLength, NULL, 0);
-    cx_hash((cx_hash_t *) &tmpContent.sha2, 0, workBuffer, dataLength, NULL, 0);
-    tmpCtx.messageSigningContext.remainingLength -= dataLength;
+    tmpCtx.messageSigningContext.remainingLength = U4BE(data, 0);
+    data += sizeof(uint32_t);
+    *length -= sizeof(uint32_t);
 
-    feed_value_str(workBuffer, dataLength, is_value_str_ascii());
+    // Initialize message header + length
+    cx_keccak_init(&global_sha3, 256);
+    cx_hash((cx_hash_t *) &global_sha3, 0, (uint8_t *) SIGN_MAGIC, sizeof(SIGN_MAGIC) - 1, NULL, 0);
+    snprintf(strings.tmp.tmp2,
+             sizeof(strings.tmp.tmp2),
+             "%u",
+             tmpCtx.messageSigningContext.remainingLength);
+    cx_hash((cx_hash_t *) &global_sha3,
+            0,
+            (uint8_t *) strings.tmp.tmp2,
+            strlen(strings.tmp.tmp2),
+            NULL,
+            0);
+    reset_ui_buffer();
+    states.sign_state = STATE_191_HASH_DISPLAY;
+    states.ui_started = false;
+    return data;
+}
 
-    if (tmpCtx.messageSigningContext.remainingLength == 0) {
+/**
+ * Feed the progressive hash with new data
+ *
+ * @param[in] data the new data
+ * @param[in] length the data length
+ * @return whether it was successful or not
+ */
+static bool feed_hash(const uint8_t *const data, const uint8_t length) {
+    if (length > tmpCtx.messageSigningContext.remainingLength) {
+        PRINTF("Error: Length mismatch ! (%u > %u)!\n",
+               length,
+               tmpCtx.messageSigningContext.remainingLength);
+        apdu_reply(0x6a80);
+        return false;
+    }
+    cx_hash((cx_hash_t *) &global_sha3, 0, data, length, NULL, 0);
+    if ((tmpCtx.messageSigningContext.remainingLength -= length) == 0) {
+        // Finalize hash
         cx_hash((cx_hash_t *) &global_sha3,
                 CX_LAST,
-                workBuffer,
+                NULL,
                 0,
                 tmpCtx.messageSigningContext.hash,
                 32);
-        cx_hash((cx_hash_t *) &tmpContent.sha2, CX_LAST, workBuffer, 0, hashMessage, 32);
+    }
+    return true;
+}
+
+/**
+ * Feed the UI with new data
+ */
+static void feed_display(void) {
+    int c;
+
+    while ((unprocessed_length() > 0) && (remaining_ui_buffer_length() > 0)) {
+        c = *(char *) unprocessed_data();
+        if (isspace(c))  // to replace all white-space characters as spaces
+        {
+            c = ' ';
+        }
+        if (isprint(c)) {
+            sprintf(remaining_ui_buffer(), "%c", (char) c);
+            processed_size += 1;
+        } else {
+            if (remaining_ui_buffer_length() >= 4)  // 4 being the fixed length of \x00
+            {
+                snprintf(remaining_ui_buffer(), remaining_ui_buffer_length(), "\\x%02x", c);
+                processed_size += 1;
+            } else {
+                // fill the rest of the UI buffer spaces, to consider the buffer full
+                memset(remaining_ui_buffer(), ' ', remaining_ui_buffer_length());
+            }
+        }
+    }
+
+    if ((remaining_ui_buffer_length() == 0) ||
+        (tmpCtx.messageSigningContext.remainingLength == 0)) {
+        if (!states.ui_started) {
+            ui_191_start();
+            states.ui_started = true;
+        } else {
+            ui_191_switch_to_message();
+        }
+    }
+
+    if ((unprocessed_length() == 0) && (tmpCtx.messageSigningContext.remainingLength > 0)) {
+        apdu_reply(0x9000);
+    }
+}
+
+/**
+ * EIP-191 APDU handler
+ *
+ * @param[in] p1 instruction parameter 1
+ * @param[in] p2 instruction parameter 2
+ * @param[in] payload received data
+ * @param[in] length data length
+ * @return whether the handling of the APDU was successful or not
+ */
+bool handleSignPersonalMessage(uint8_t p1,
+                               uint8_t p2,
+                               const uint8_t *const payload,
+                               uint8_t length) {
+    const uint8_t *data = payload;
+    uint16_t u16_length = length;
 
+    (void) p2;
+    processed_size = 0;
+    if (p1 == P1_FIRST) {
+        if ((data = first_apdu_data(data, &u16_length)) == NULL) {
+            return false;
+        }
+        processed_size = data - payload;
+    } else if (p1 != P1_MORE) {
+        PRINTF("Error: Unexpected P1 (%u)!\n", p1);
+        apdu_reply(0x6B00);
+        return false;
+    }
+
+    if (!feed_hash(data, u16_length)) {
+        return false;
+    }
+
+    if (states.sign_state == STATE_191_HASH_DISPLAY) {
+        feed_display();
+    } else  // hash only
+    {
+        if (tmpCtx.messageSigningContext.remainingLength == 0) {
 #ifdef NO_CONSENT
-        io_seproxyhal_touch_signMessage_ok(NULL);
-#else   // NO_CONSENT
-        ux_flow_init(0, ux_sign_flow, NULL);
-#endif  // NO_CONSENT
+            io_seproxyhal_touch_signMessage_ok();
+#else
+            ui_191_switch_to_sign();
+#endif
+        } else {
+            apdu_reply(0x9000);
+        }
+    }
+    return true;
+}
 
-        *flags |= IO_ASYNCH_REPLY;
+/**
+ * Decide whether to show the question to show more of the message or not
+ */
+void question_switcher(void) {
+    if ((states.sign_state == STATE_191_HASH_DISPLAY) &&
+        ((tmpCtx.messageSigningContext.remainingLength > 0) || (unprocessed_length() > 0))) {
+        ui_191_switch_to_question();
+    } else {
+        // Go to Sign / Cancel
+        ui_191_switch_to_sign();
+    }
+}
 
+/**
+ * The user has decided to skip the rest of the message
+ */
+void skip_rest_of_message(void) {
+    states.sign_state = STATE_191_HASH_ONLY;
+    if (tmpCtx.messageSigningContext.remainingLength > 0) {
+        apdu_reply(0x9000);
     } else {
-        THROW(0x9000);
+        ui_191_switch_to_sign();
+    }
+}
+
+/**
+ * The user has decided to see the next chunk of the message
+ */
+void continue_displaying_message(void) {
+    reset_ui_buffer();
+    if (unprocessed_length() > 0) {
+        feed_display();
     }
 }
diff --git a/src_features/signMessage/sign_message.h b/src_features/signMessage/sign_message.h
new file mode 100644
index 000000000..6d35e4979
--- /dev/null
+++ b/src_features/signMessage/sign_message.h
@@ -0,0 +1,12 @@
+#ifndef SIGN_MESSAGE_H_
+#define SIGN_MESSAGE_H_
+
+#define UI_191_BUFFER strings.tmp.tmp
+
+typedef enum { STATE_191_HASH_DISPLAY = 0, STATE_191_HASH_ONLY } sign_message_state;
+
+void question_switcher(void);
+void skip_rest_of_message(void);
+void continue_displaying_message(void);
+
+#endif  // SIGN_MESSAGE_H_
diff --git a/src_features/signMessage/ui_common_signMessage.c b/src_features/signMessage/ui_common_signMessage.c
index e2a901ba4..eb6707d35 100644
--- a/src_features/signMessage/ui_common_signMessage.c
+++ b/src_features/signMessage/ui_common_signMessage.c
@@ -1,16 +1,15 @@
 #include "os_io_seproxyhal.h"
-#include "shared_context.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
-unsigned int io_seproxyhal_touch_signMessage_ok(__attribute__((unused)) const bagl_element_t *e) {
+unsigned int io_seproxyhal_touch_signMessage_ok(void) {
     uint8_t privateKeyData[INT256_LENGTH];
     uint8_t signature[100];
     cx_ecfp_private_key_t privateKey;
     uint32_t tx = 0;
     io_seproxyhal_io_heartbeat();
     os_perso_derive_node_bip32(CX_CURVE_256K1,
-                               tmpCtx.messageSigningContext.bip32Path,
-                               tmpCtx.messageSigningContext.pathLength,
+                               tmpCtx.messageSigningContext.bip32.path,
+                               tmpCtx.messageSigningContext.bip32.length,
                                privateKeyData,
                                NULL);
     io_seproxyhal_io_heartbeat();
@@ -46,8 +45,7 @@ unsigned int io_seproxyhal_touch_signMessage_ok(__attribute__((unused)) const ba
     return 0;  // do not redraw the widget
 }
 
-unsigned int io_seproxyhal_touch_signMessage_cancel(__attribute__((unused))
-                                                    const bagl_element_t *e) {
+unsigned int io_seproxyhal_touch_signMessage_cancel(void) {
     reset_app_context();
     G_io_apdu_buffer[0] = 0x69;
     G_io_apdu_buffer[1] = 0x85;
diff --git a/src_features/signMessage/ui_flow_signMessage.c b/src_features/signMessage/ui_flow_signMessage.c
deleted file mode 100644
index ee8e39eb8..000000000
--- a/src_features/signMessage/ui_flow_signMessage.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "shared_context.h"
-#include "ui_callbacks.h"
-
-// clang-format off
-UX_STEP_NOCB(
-    ux_sign_flow_1_step,
-    pnn,
-    {
-      &C_icon_certificate,
-      "Sign",
-      "message",
-    });
-UX_STEP_NOCB(
-    ux_sign_flow_2_step,
-    bnnn_paging,
-    {
-      .title = "Message",
-      .text = strings.tmp.tmp,
-    });
-UX_STEP_CB(
-    ux_sign_flow_3_step,
-    pbb,
-    io_seproxyhal_touch_signMessage_ok(NULL),
-    {
-      &C_icon_validate_14,
-      "Sign",
-      "message",
-    });
-UX_STEP_CB(
-    ux_sign_flow_4_step,
-    pbb,
-    io_seproxyhal_touch_signMessage_cancel(NULL),
-    {
-      &C_icon_crossmark,
-      "Cancel",
-      "signature",
-    });
-// clang-format on
-
-UX_FLOW(ux_sign_flow,
-        &ux_sign_flow_1_step,
-        &ux_sign_flow_2_step,
-        &ux_sign_flow_3_step,
-        &ux_sign_flow_4_step);
diff --git a/src_features/signMessageEIP712/cmd_signMessage712.c b/src_features/signMessageEIP712/cmd_signMessage712.c
index bc9443e62..847c40a10 100644
--- a/src_features/signMessageEIP712/cmd_signMessage712.c
+++ b/src_features/signMessageEIP712/cmd_signMessage712.c
@@ -1,16 +1,14 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 #include "utils.h"
-#include "ui_flow.h"
+#include "common_ui.h"
 
 void handleSignEIP712Message(uint8_t p1,
                              uint8_t p2,
-                             uint8_t *workBuffer,
+                             const uint8_t *workBuffer,
                              uint16_t dataLength,
                              unsigned int *flags,
                              unsigned int *tx) {
-    uint8_t i;
-
     UNUSED(tx);
     if ((p1 != 00) || (p2 != 00)) {
         THROW(0x6B00);
@@ -18,38 +16,20 @@ void handleSignEIP712Message(uint8_t p1,
     if (appState != APP_STATE_IDLE) {
         reset_app_context();
     }
-    if (dataLength < 1) {
-        PRINTF("Invalid data\n");
-        THROW(0x6a80);
-    }
-    tmpCtx.messageSigningContext712.pathLength = workBuffer[0];
-    if ((tmpCtx.messageSigningContext712.pathLength < 0x01) ||
-        (tmpCtx.messageSigningContext712.pathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
-    }
-    workBuffer++;
-    dataLength--;
-    for (i = 0; i < tmpCtx.messageSigningContext712.pathLength; i++) {
-        if (dataLength < 4) {
-            PRINTF("Invalid data\n");
-            THROW(0x6a80);
-        }
-        tmpCtx.messageSigningContext712.bip32Path[i] = U4BE(workBuffer, 0);
-        workBuffer += 4;
-        dataLength -= 4;
-    }
-    if (dataLength < 32 + 32) {
-        PRINTF("Invalid data\n");
+
+    workBuffer = parseBip32(workBuffer, &dataLength, &tmpCtx.messageSigningContext.bip32);
+
+    if (workBuffer == NULL || dataLength < 32 + 32) {
         THROW(0x6a80);
     }
+
     memmove(tmpCtx.messageSigningContext712.domainHash, workBuffer, 32);
     memmove(tmpCtx.messageSigningContext712.messageHash, workBuffer + 32, 32);
 
 #ifdef NO_CONSENT
-    io_seproxyhal_touch_signMessage_ok(NULL);
+    io_seproxyhal_touch_signMessage_ok();
 #else   // NO_CONSENT
-    ux_flow_init(0, ux_sign_712_v0_flow, NULL);
+    ui_sign_712_v0();
 #endif  // NO_CONSENT
 
     *flags |= IO_ASYNCH_REPLY;
diff --git a/src_features/signMessageEIP712/ui_common_signMessage712.c b/src_features/signMessageEIP712/ui_common_signMessage712.c
index e67cc4e36..4d5e266fa 100644
--- a/src_features/signMessageEIP712/ui_common_signMessage712.c
+++ b/src_features/signMessageEIP712/ui_common_signMessage712.c
@@ -1,6 +1,6 @@
 #include "os_io_seproxyhal.h"
 #include "shared_context.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01};
 
@@ -34,8 +34,8 @@ unsigned int io_seproxyhal_touch_signMessage712_v0_ok(__attribute__((unused))
     PRINTF("EIP712 hash to sign %.*H\n", 32, hash);
     io_seproxyhal_io_heartbeat();
     os_perso_derive_node_bip32(CX_CURVE_256K1,
-                               tmpCtx.messageSigningContext712.bip32Path,
-                               tmpCtx.messageSigningContext712.pathLength,
+                               tmpCtx.messageSigningContext712.bip32.path,
+                               tmpCtx.messageSigningContext712.bip32.length,
                                privateKeyData,
                                NULL);
     io_seproxyhal_io_heartbeat();
diff --git a/src_features/signTx/cmd_signTx.c b/src_features/signTx/cmd_signTx.c
index 3b084f549..7a12527a3 100644
--- a/src_features/signTx/cmd_signTx.c
+++ b/src_features/signTx/cmd_signTx.c
@@ -1,54 +1,43 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "feature_signTx.h"
 #include "eth_plugin_interface.h"
 
 void handleSign(uint8_t p1,
                 uint8_t p2,
-                uint8_t *workBuffer,
+                const uint8_t *workBuffer,
                 uint16_t dataLength,
                 unsigned int *flags,
                 unsigned int *tx) {
     UNUSED(tx);
     parserStatus_e txResult;
-    uint32_t i;
 
     if (os_global_pin_is_validated() != BOLOS_UX_OK) {
         PRINTF("Device is PIN-locked");
         THROW(0x6982);
     }
     if (p1 == P1_FIRST) {
-        if (dataLength < 1) {
-            PRINTF("Invalid data\n");
-            THROW(0x6a80);
-        }
         if (appState != APP_STATE_IDLE) {
             reset_app_context();
         }
         appState = APP_STATE_SIGNING_TX;
-        tmpCtx.transactionContext.pathLength = workBuffer[0];
-        if ((tmpCtx.transactionContext.pathLength < 0x01) ||
-            (tmpCtx.transactionContext.pathLength > MAX_BIP32_PATH)) {
-            PRINTF("Invalid path\n");
+
+        workBuffer = parseBip32(workBuffer, &dataLength, &tmpCtx.transactionContext.bip32);
+
+        if (workBuffer == NULL) {
             THROW(0x6a80);
         }
-        workBuffer++;
-        dataLength--;
-        for (i = 0; i < tmpCtx.transactionContext.pathLength; i++) {
-            if (dataLength < 4) {
-                PRINTF("Invalid data\n");
-                THROW(0x6a80);
-            }
-            tmpCtx.transactionContext.bip32Path[i] = U4BE(workBuffer, 0);
-            workBuffer += 4;
-            dataLength -= 4;
-        }
+
         tmpContent.txContent.dataPresent = false;
         dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_UNAVAILABLE;
 
         initTx(&txContext, &global_sha3, &tmpContent.txContent, customProcessor, NULL);
 
+        if (dataLength < 1) {
+            PRINTF("Invalid data\n");
+            THROW(0x6a80);
+        }
+
         // EIP 2718: TransactionType might be present before the TransactionPayload.
         uint8_t txType = *workBuffer;
         if (txType >= MIN_TX_TYPE && txType <= MAX_TX_TYPE) {
diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c
index eb8e10f10..1c4164677 100644
--- a/src_features/signTx/logic_signTx.c
+++ b/src_features/signTx/logic_signTx.c
@@ -1,7 +1,5 @@
 #include "shared_context.h"
 #include "utils.h"
-#include "ui_callbacks.h"
-#include "ui_flow.h"
 #include "feature_signTx.h"
 #ifdef HAVE_STARKWARE
 #include "stark_utils.h"
@@ -9,6 +7,8 @@
 #include "eth_plugin_handler.h"
 #include "network.h"
 #include "ethUtils.h"
+#include "common_ui.h"
+#include "ui_callbacks.h"
 
 #define ERR_SILENT_MODE_CHECK_FAILED 0x6001
 
@@ -144,7 +144,7 @@ customStatus_e customProcessor(txContext_t *context) {
             dataContext.tokenContext.fieldOffset = 0;
             if (fieldPos == 0) {
                 array_hexstr(strings.tmp.tmp, dataContext.tokenContext.data, 4);
-                ux_flow_init(0, ux_confirm_selector_flow, NULL);
+                ui_confirm_selector();
             } else {
                 uint32_t offset = 0;
                 uint32_t i;
@@ -159,7 +159,7 @@ customStatus_e customProcessor(txContext_t *context) {
                         strings.tmp.tmp[offset++] = ':';
                     }
                 }
-                ux_flow_init(0, ux_confirm_parameter_flow, NULL);
+                ui_confirm_parameter();
             }
         } else {
             return CUSTOM_HANDLED;
@@ -231,15 +231,26 @@ static void feesToString(uint256_t *rawFee, char *displayBuffer, uint32_t displa
     i = 0;
     tickerOffset = 0;
     memset(displayBuffer, 0, displayBufferSize);
+
     while (feeTicker[tickerOffset]) {
+        if ((uint32_t) tickerOffset >= displayBufferSize) {
+            break;
+        }
+
         displayBuffer[tickerOffset] = feeTicker[tickerOffset];
         tickerOffset++;
     }
     while (G_io_apdu_buffer[i]) {
+        if ((uint32_t) (tickerOffset) + i >= displayBufferSize) {
+            break;
+        }
         displayBuffer[tickerOffset + i] = G_io_apdu_buffer[i];
         i++;
     }
-    displayBuffer[tickerOffset + i] = '\0';
+
+    if ((uint32_t) (tickerOffset) + i < displayBufferSize) {
+        displayBuffer[tickerOffset + i] = '\0';
+    }
 }
 
 // Compute the fees, transform it to a string, prepend a ticker to it and copy everything to
@@ -282,8 +293,8 @@ static void get_public_key(uint8_t *out, uint8_t outLength) {
     }
 
     os_perso_derive_node_bip32(CX_CURVE_256K1,
-                               tmpCtx.transactionContext.bip32Path,
-                               tmpCtx.transactionContext.pathLength,
+                               tmpCtx.transactionContext.bip32.path,
+                               tmpCtx.transactionContext.bip32.length,
                                privateKeyData,
                                NULL);
     cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c
index 3d2719730..ef8171f25 100644
--- a/src_features/signTx/ui_common_signTx.c
+++ b/src_features/signTx/ui_common_signTx.c
@@ -1,7 +1,7 @@
 #include "os_io_seproxyhal.h"
 #include "shared_context.h"
 #include "utils.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_element_t *e) {
     uint8_t privateKeyData[INT256_LENGTH];
@@ -10,8 +10,8 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen
     uint32_t tx = 0;
     io_seproxyhal_io_heartbeat();
     os_perso_derive_node_bip32(CX_CURVE_256K1,
-                               tmpCtx.transactionContext.bip32Path,
-                               tmpCtx.transactionContext.pathLength,
+                               tmpCtx.transactionContext.bip32.path,
+                               tmpCtx.transactionContext.bip32.length,
                                privateKeyData,
                                NULL);
     cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
diff --git a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c b/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c
index 54edf0985..24cfa197e 100644
--- a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c
+++ b/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c
@@ -4,37 +4,37 @@
 #include "apdu_constants.h"
 #include "stark_utils.h"
 #include "feature_stark_getPublicKey.h"
-#include "ui_flow.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 void handleStarkwareGetPublicKey(uint8_t p1,
                                  uint8_t p2,
-                                 uint8_t *dataBuffer,
+                                 const uint8_t *dataBuffer,
                                  uint16_t dataLength,
                                  unsigned int *flags,
                                  unsigned int *tx) {
-    UNUSED(dataLength);
-    uint8_t privateKeyData[32];
-    uint32_t bip32Path[MAX_BIP32_PATH];
-    uint32_t i;
-    uint8_t bip32PathLength = *(dataBuffer++);
+    bip32_path_t bip32;
     cx_ecfp_private_key_t privateKey;
+    uint8_t privateKeyData[32];
+
     reset_app_context();
-    if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
-    }
+
     if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
         THROW(0x6B00);
     }
+
     if (p2 != 0) {
         THROW(0x6B00);
     }
-    for (i = 0; i < bip32PathLength; i++) {
-        bip32Path[i] = U4BE(dataBuffer, 0);
-        dataBuffer += 4;
+
+    dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32);
+
+    if (dataBuffer == NULL) {
+        THROW(0x6a80);
     }
+
     io_seproxyhal_io_heartbeat();
-    starkDerivePrivateKey(bip32Path, bip32PathLength, privateKeyData);
+    starkDerivePrivateKey(bip32.path, bip32.length, privateKeyData);
     cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
     io_seproxyhal_io_heartbeat();
     cx_ecfp_generate_pair(CX_CURVE_Stark256, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
@@ -56,7 +56,7 @@ void handleStarkwareGetPublicKey(uint8_t p1,
                  "0x%.*H",
                  32,
                  tmpCtx.publicKeyContext.publicKey.W + 1);
-        ux_flow_init(0, ux_display_stark_public_flow, NULL);
+        ui_display_stark_public();
 
         *flags |= IO_ASYNCH_REPLY;
     }
diff --git a/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c b/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c
index 94a6658fd..31b97144f 100644
--- a/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c
+++ b/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c
@@ -1,7 +1,7 @@
 #ifdef HAVE_STARKWARE
 
 #include "shared_context.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 #include "feature_stark_getPublicKey.h"
 
 unsigned int io_seproxyhal_touch_stark_pubkey_ok(__attribute__((unused)) const bagl_element_t *e) {
diff --git a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c b/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c
index 1796fe5e7..900221ddc 100644
--- a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c
+++ b/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c
@@ -2,12 +2,12 @@
 
 #include "shared_context.h"
 #include "apdu_constants.h"
-#include "ui_flow.h"
 #include "ethUtils.h"
+#include "common_ui.h"
 
 void handleStarkwareProvideQuantum(uint8_t p1,
                                    __attribute__((unused)) uint8_t p2,
-                                   uint8_t *dataBuffer,
+                                   const uint8_t *dataBuffer,
                                    uint16_t dataLength,
                                    __attribute__((unused)) unsigned int *flags,
                                    __attribute__((unused)) unsigned int *tx) {
@@ -35,7 +35,7 @@ void handleStarkwareProvideQuantum(uint8_t p1,
         THROW(0x6700);
     }
     if (p1 == STARK_QUANTUM_LEGACY) {
-        addressZero = allzeroes(dataBuffer, 20);
+        addressZero = allzeroes((void *) dataBuffer, 20);
     }
     if ((p1 != STARK_QUANTUM_ETH) && !addressZero) {
         for (i = 0; i < MAX_ITEMS; i++) {
diff --git a/src_features/stark_sign/cmd_stark_sign.c b/src_features/stark_sign/cmd_stark_sign.c
index 12f7da790..e27c2a0b2 100644
--- a/src_features/stark_sign/cmd_stark_sign.c
+++ b/src_features/stark_sign/cmd_stark_sign.c
@@ -3,10 +3,10 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 #include "stark_utils.h"
-#include "ui_flow.h"
 #include "poorstream.h"
-#include "ui_callbacks.h"
 #include "ethUtils.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 #define U8BE(buf, off) \
     (uint64_t)((((uint64_t) U4BE(buf, off)) << 32) | (((uint64_t) U4BE(buf, off + 4)) & 0xFFFFFFFF))
@@ -20,7 +20,7 @@ void handleStarkwareSignMessage(uint8_t p1,
                                 __attribute__((unused)) unsigned int *tx) {
     uint8_t privateKeyData[INT256_LENGTH];
     uint32_t i;
-    uint8_t bip32PathLength = *(dataBuffer);
+    uint8_t bip32PathLength;
     uint8_t offset = 1;
     cx_ecfp_private_key_t privateKey;
     poorstream_t bitstream;
@@ -29,10 +29,19 @@ void handleStarkwareSignMessage(uint8_t p1,
     uint8_t protocol = 2;
     uint8_t preOffset, postOffset;
     uint8_t zeroTest;
+
     // Initial checks
     if (appState != APP_STATE_IDLE) {
         reset_app_context();
     }
+
+    if (dataLength < 1) {
+        PRINTF("Invalid data\n");
+        THROW(0x6a80);
+    }
+
+    bip32PathLength = *(dataBuffer);
+
     if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
         PRINTF("Invalid path\n");
         THROW(0x6a80);
@@ -70,10 +79,10 @@ void handleStarkwareSignMessage(uint8_t p1,
     if (p2 != 0) {
         THROW(0x6B00);
     }
-    tmpCtx.transactionContext.pathLength = bip32PathLength;
+    tmpCtx.transactionContext.bip32.length = bip32PathLength;
     for (i = 0; i < bip32PathLength; i++) {
-        tmpCtx.transactionContext.bip32Path[i] = U4BE(dataBuffer, offset);
-        PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32Path[i]);
+        tmpCtx.transactionContext.bip32.path[i] = U4BE(dataBuffer, offset);
+        PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32.path[i]);
         offset += 4;
     }
     // Discard the path to use part of dataBuffer as a temporary buffer
@@ -205,7 +214,9 @@ void handleStarkwareSignMessage(uint8_t p1,
         cx_ecfp_public_key_t publicKey;
         // Check if the transfer is a self transfer
         io_seproxyhal_io_heartbeat();
-        starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, bip32PathLength, privateKeyData);
+        starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path,
+                              bip32PathLength,
+                              privateKeyData);
         cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
         io_seproxyhal_io_heartbeat();
         cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1);
@@ -238,20 +249,9 @@ void handleStarkwareSignMessage(uint8_t p1,
         }
     }
     if (order) {
-        ux_flow_init(0, ux_stark_limit_order_flow, NULL);
+        ui_stark_limit_order();
     } else {
-        if (selfTransfer) {
-            ux_flow_init(
-                0,
-                (dataContext.starkContext.conditional ? ux_stark_self_transfer_conditional_flow
-                                                      : ux_stark_self_transfer_flow),
-                NULL);
-        } else {
-            ux_flow_init(0,
-                         (dataContext.starkContext.conditional ? ux_stark_transfer_conditional_flow
-                                                               : ux_stark_transfer_flow),
-                         NULL);
-        }
+        ui_stark_transfer(selfTransfer, dataContext.starkContext.conditional);
     }
 
     *flags |= IO_ASYNCH_REPLY;
diff --git a/src_features/stark_sign/ui_common_stark_sign.c b/src_features/stark_sign/ui_common_stark_sign.c
index 533f67f56..a45f7f918 100644
--- a/src_features/stark_sign/ui_common_stark_sign.c
+++ b/src_features/stark_sign/ui_common_stark_sign.c
@@ -3,15 +3,15 @@
 #include "os_io_seproxyhal.h"
 #include "shared_context.h"
 #include "stark_utils.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_stark_ok(__attribute__((unused)) const bagl_element_t *e) {
     uint8_t privateKeyData[32];
     uint8_t signature[72];
     uint32_t tx = 0;
     io_seproxyhal_io_heartbeat();
-    starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path,
-                          tmpCtx.transactionContext.pathLength,
+    starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path,
+                          tmpCtx.transactionContext.bip32.length,
                           privateKeyData);
     io_seproxyhal_io_heartbeat();
     stark_sign(signature,
diff --git a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c b/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c
index e899816a2..d6366548d 100644
--- a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c
+++ b/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c
@@ -3,46 +3,43 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 #include "stark_utils.h"
-#include "ui_flow.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
+#include "os_io_seproxyhal.h"
 
 void handleStarkwareUnsafeSign(uint8_t p1,
                                uint8_t p2,
-                               uint8_t *dataBuffer,
+                               const uint8_t *dataBuffer,
                                uint16_t dataLength,
                                unsigned int *flags,
                                __attribute__((unused)) unsigned int *tx) {
-    uint32_t i;
     uint8_t privateKeyData[INT256_LENGTH];
     cx_ecfp_public_key_t publicKey;
     cx_ecfp_private_key_t privateKey;
-    uint8_t bip32PathLength = *(dataBuffer);
-    uint8_t offset = 1;
+
     // Initial checks
     if (appState != APP_STATE_IDLE) {
         reset_app_context();
     }
-    if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) {
-        PRINTF("Invalid path\n");
-        THROW(0x6a80);
-    }
+
     if ((p1 != 0) || (p2 != 0)) {
         THROW(0x6B00);
     }
 
-    if (dataLength != 32 + 4 * bip32PathLength + 1) {
-        THROW(0x6700);
+    dataBuffer = parseBip32(dataBuffer, &dataLength, &tmpCtx.transactionContext.bip32);
+
+    if (dataBuffer == NULL) {
+        THROW(0x6a80);
     }
 
-    tmpCtx.transactionContext.pathLength = bip32PathLength;
-    for (i = 0; i < bip32PathLength; i++) {
-        tmpCtx.transactionContext.bip32Path[i] = U4BE(dataBuffer, offset);
-        PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32Path[i]);
-        offset += 4;
+    if (dataLength != 32) {
+        THROW(0x6700);
     }
-    memmove(dataContext.starkContext.w2, dataBuffer + offset, 32);
+
+    memmove(dataContext.starkContext.w2, dataBuffer, 32);
     io_seproxyhal_io_heartbeat();
-    starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, bip32PathLength, privateKeyData);
+    starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path,
+                          tmpCtx.transactionContext.bip32.length,
+                          privateKeyData);
     cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
     io_seproxyhal_io_heartbeat();
     cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1);
@@ -50,7 +47,7 @@ void handleStarkwareUnsafeSign(uint8_t p1,
     explicit_bzero(privateKeyData, sizeof(privateKeyData));
     io_seproxyhal_io_heartbeat();
     memmove(dataContext.starkContext.w1, publicKey.W + 1, 32);
-    ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL);
+    ui_stark_unsafe_sign();
 
     *flags |= IO_ASYNCH_REPLY;
 }
diff --git a/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c b/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c
index 4c84e0b18..4774627b8 100644
--- a/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c
+++ b/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c
@@ -3,7 +3,7 @@
 #include "os_io_seproxyhal.h"
 #include "shared_context.h"
 #include "stark_utils.h"
-#include "ui_callbacks.h"
+#include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(__attribute__((unused))
                                                       const bagl_element_t *e) {
@@ -13,8 +13,8 @@ unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(__attribute__((unused))
     unsigned int info = 0;
     uint32_t tx = 0;
     io_seproxyhal_io_heartbeat();
-    starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path,
-                          tmpCtx.transactionContext.pathLength,
+    starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path,
+                          tmpCtx.transactionContext.bip32.length,
                           privateKeyData);
     io_seproxyhal_io_heartbeat();
     cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
diff --git a/src_plugins/compound/compound_plugin.c b/src_plugins/compound/compound_plugin.c
deleted file mode 100644
index cbb68dd4c..000000000
--- a/src_plugins/compound/compound_plugin.c
+++ /dev/null
@@ -1,243 +0,0 @@
-#include <string.h>
-#include "eth_plugin_interface.h"
-#include "shared_context.h"       // TODO : rewrite as independant code
-#include "eth_plugin_internal.h"  // TODO : rewrite as independant code
-#include "utils.h"
-#include "ethUtils.h"
-
-typedef enum {
-    COMPOUND_REDEEM_UNDERLYING = 0,
-    COMPOUND_REDEEM,
-    COMPOUND_MINT,
-    CETH_MINT
-} compoundSelector_t;
-
-static const uint8_t COMPOUND_EXPECTED_DATA_SIZE[] = {
-    4 + 32,
-    4 + 32,
-    4 + 32,
-    4,
-};
-
-// redeemUnderlying : redeemAmount (32)
-// redeem underlying token
-// redeem : redeemTokens (32)
-// redeem Ctoken
-// mint : mintAmount (32)
-// lend some token
-// mint :
-// lend some Ether
-
-typedef struct compound_parameters_t {
-    uint8_t selectorIndex;
-    uint8_t amount[32];
-    char ticker_1[MAX_TICKER_LEN];
-    uint8_t decimals;
-} compound_parameters_t;
-
-typedef struct underlying_asset_decimals_t {
-    char c_ticker[MAX_TICKER_LEN];
-    uint8_t decimals;
-} underlying_asset_decimals_t;
-
-/* Sadly, we don't have the information about the underlying asset's decimals, which can differ from
-the cToken decimals. Therefore, we hardcode a binding table. If Compound adds a lot of token in the
-future, we will have to move to a CAL based architecture instead, as this one doesn't scale well.*/
-#define NUM_COMPOUND_BINDINGS 9
-const underlying_asset_decimals_t UNDERLYING_ASSET_DECIMALS[NUM_COMPOUND_BINDINGS] = {
-    {"cDAI", 18},
-    {"CETH", 18},
-    {"CUSDC", 6},
-    {"CZRX", 18},
-    {"CUSDT", 6},
-    {"CBTC", 8},
-    {"CBAT", 18},
-    {"CREP", 18},
-    {"cSAI", 18},
-};
-
-bool get_underlying_asset_decimals(char *compound_ticker, uint8_t *out_decimals) {
-    for (size_t i = 0; i < NUM_COMPOUND_BINDINGS; i++) {
-        underlying_asset_decimals_t *binding =
-            (underlying_asset_decimals_t *) PIC(&UNDERLYING_ASSET_DECIMALS[i]);
-        if (strncmp(binding->c_ticker,
-                    compound_ticker,
-                    strnlen(binding->c_ticker, MAX_TICKER_LEN)) == 0) {
-            *out_decimals = binding->decimals;
-            return true;
-        }
-    }
-    return false;
-}
-
-void compound_plugin_call(int message, void *parameters) {
-    switch (message) {
-        case ETH_PLUGIN_INIT_CONTRACT: {
-            ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters;
-            compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext;
-            size_t i;
-            for (i = 0; i < NUM_COMPOUND_SELECTORS; i++) {
-                if (memcmp((uint8_t *) PIC(COMPOUND_SELECTORS[i]), msg->selector, SELECTOR_SIZE) ==
-                    0) {
-                    context->selectorIndex = i;
-                    break;
-                }
-            }
-            // enforce that ETH amount should be 0, except in ceth.mint case
-            if (!allzeroes(msg->pluginSharedRO->txContent->value.value, 32)) {
-                if (context->selectorIndex != CETH_MINT) {
-                    PRINTF("Eth amount is not zero and token minted is not CETH!\n");
-                    msg->result = ETH_PLUGIN_RESULT_ERROR;
-                    break;
-                }
-            }
-            if (i == NUM_COMPOUND_SELECTORS) {
-                PRINTF("Unknown selector %.*H\n", SELECTOR_SIZE, msg->selector);
-                msg->result = ETH_PLUGIN_RESULT_ERROR;
-                break;
-            }
-            if (msg->dataSize != COMPOUND_EXPECTED_DATA_SIZE[context->selectorIndex]) {
-                PRINTF("Unexpected data size for command %d expected %d got %d\n",
-                       context->selectorIndex,
-                       COMPOUND_EXPECTED_DATA_SIZE[context->selectorIndex],
-                       msg->dataSize);
-                msg->result = ETH_PLUGIN_RESULT_ERROR;
-                break;
-            }
-            if (context->selectorIndex == CETH_MINT) {
-                // ETH amount 0x1234 is stored 0x12340000...000 instead of 0x00....001234, so we
-                // strip the following zeroes when copying
-                memset(context->amount, 0, sizeof(context->amount));
-                memmove(context->amount + sizeof(context->amount) -
-                            msg->pluginSharedRO->txContent->value.length,
-                        msg->pluginSharedRO->txContent->value.value,
-                        msg->pluginSharedRO->txContent->value.length);
-            }
-            PRINTF("compound plugin inititialized\n");
-            msg->result = ETH_PLUGIN_RESULT_OK;
-        } break;
-
-        case ETH_PLUGIN_PROVIDE_PARAMETER: {
-            ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters;
-            compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext;
-            PRINTF("compound plugin provide parameter %d %.*H\n",
-                   msg->parameterOffset,
-                   32,
-                   msg->parameter);
-            if (context->selectorIndex != CETH_MINT) {
-                switch (msg->parameterOffset) {
-                    case 4:
-                        memmove(context->amount, msg->parameter, 32);
-                        msg->result = ETH_PLUGIN_RESULT_OK;
-                        break;
-                    default:
-                        PRINTF("Unhandled parameter offset\n");
-                        msg->result = ETH_PLUGIN_RESULT_ERROR;
-                        break;
-                }
-            } else {
-                PRINTF("CETH contract expects no parameters\n");
-                msg->result = ETH_PLUGIN_RESULT_ERROR;
-            }
-        } break;
-
-        case ETH_PLUGIN_FINALIZE: {
-            ethPluginFinalize_t *msg = (ethPluginFinalize_t *) parameters;
-            PRINTF("compound plugin finalize\n");
-            msg->tokenLookup1 = msg->pluginSharedRO->txContent->destination;
-            msg->numScreens = 2;
-            msg->uiType = ETH_UI_TYPE_GENERIC;
-            msg->result = ETH_PLUGIN_RESULT_OK;
-        } break;
-
-        case ETH_PLUGIN_PROVIDE_INFO: {
-            ethPluginProvideInfo_t *msg = (ethPluginProvideInfo_t *) parameters;
-            compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext;
-            PRINTF("compound plugin provide token: %d\n", (msg->item1 != NULL));
-            if (msg->item1 != NULL) {
-                strlcpy(context->ticker_1, msg->item1->token.ticker, MAX_TICKER_LEN);
-                switch (context->selectorIndex) {
-                    case COMPOUND_REDEEM_UNDERLYING:
-                    case COMPOUND_MINT:
-                    case CETH_MINT:
-                        msg->result =
-                            get_underlying_asset_decimals(context->ticker_1, &context->decimals)
-                                ? ETH_PLUGIN_RESULT_OK
-                                : ETH_PLUGIN_RESULT_FALLBACK;
-                        break;
-
-                    // Only case where we use the compound contract decimals
-                    case COMPOUND_REDEEM:
-                        context->decimals = msg->item1->token.decimals;
-                        msg->result = ETH_PLUGIN_RESULT_OK;
-                        break;
-
-                    default:
-                        msg->result = ETH_PLUGIN_RESULT_FALLBACK;
-                        break;
-                }
-            } else {
-                msg->result = ETH_PLUGIN_RESULT_FALLBACK;
-            }
-        } break;
-
-        case ETH_PLUGIN_QUERY_CONTRACT_ID: {
-            ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters;
-            compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext;
-            strlcpy(msg->name, "Type", msg->nameLength);
-            switch (context->selectorIndex) {
-                case COMPOUND_REDEEM_UNDERLYING:
-                case COMPOUND_REDEEM:
-                    strlcpy(msg->version, "Redeem", msg->versionLength);
-                    break;
-
-                case COMPOUND_MINT:
-                case CETH_MINT:
-                    strlcpy(msg->version, "Lend", msg->versionLength);
-                    break;
-
-                default:
-                    break;
-            }
-            strlcat(msg->version, " Assets", msg->versionLength);
-            msg->result = ETH_PLUGIN_RESULT_OK;
-        } break;
-
-        case ETH_PLUGIN_QUERY_CONTRACT_UI: {
-            ethQueryContractUI_t *msg = (ethQueryContractUI_t *) parameters;
-            compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext;
-            switch (msg->screenIndex) {
-                case 0: {
-                    strlcpy(msg->title, "Amount", msg->titleLength);
-                    char *ticker_ptr = context->ticker_1;
-                    /* skip "c" in front of cToken unless we use "redeem", as
-                    redeem is the only operation dealing with a cToken amount */
-                    if (context->selectorIndex != COMPOUND_REDEEM) {
-                        ticker_ptr++;
-                    }
-                    amountToString(context->amount,
-                                   sizeof(context->amount),
-                                   context->decimals,
-                                   ticker_ptr,
-                                   msg->msg,
-                                   100);
-                    msg->result = ETH_PLUGIN_RESULT_OK;
-                } break;
-
-                case 1:
-                    strlcpy(msg->title, "Contract", msg->titleLength);
-                    strlcpy(msg->msg, "Compound ", msg->msgLength);
-                    strlcat(msg->msg,
-                            context->ticker_1 + 1,
-                            msg->msgLength);  // remove the 'c' char at beginning of compound ticker
-                    msg->result = ETH_PLUGIN_RESULT_OK;
-                    break;
-                default:
-                    break;
-            }
-        } break;
-
-        default:
-            PRINTF("Unhandled message %d\n", message);
-    }
-}
diff --git a/src_plugins/starkware/starkware_plugin.c b/src_plugins/starkware/starkware_plugin.c
index 9800f7c60..3937adaaa 100644
--- a/src_plugins/starkware/starkware_plugin.c
+++ b/src_plugins/starkware/starkware_plugin.c
@@ -367,8 +367,8 @@ void starkware_get_source_address(char *destination) {
     cx_ecfp_private_key_t privateKey;
     cx_ecfp_public_key_t publicKey;
     os_perso_derive_node_bip32(CX_CURVE_256K1,
-                               tmpCtx.transactionContext.bip32Path,
-                               tmpCtx.transactionContext.pathLength,
+                               tmpCtx.transactionContext.bip32.path,
+                               tmpCtx.transactionContext.bip32.length,
                                privateKeyData,
                                NULL);
     cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);


Test patch:
diff --git a/icons/nanos_app_tecratestnet.gif b/icons/nanos_app_tecratestnet.gif
new file mode 100755
index 000000000..367ccf4e0
Binary files /dev/null and b/icons/nanos_app_tecratestnet.gif differ
diff --git a/icons/nanox_app_tecratestnet.gif b/icons/nanox_app_tecratestnet.gif
new file mode 100755
index 000000000..596fa3899
Binary files /dev/null and b/icons/nanox_app_tecratestnet.gif differ
diff --git a/makefile_conf/chain/tecratestnet.mk b/makefile_conf/chain/tecratestnet.mk
new file mode 100644
index 000000000..8091b8967
--- /dev/null
+++ b/makefile_conf/chain/tecratestnet.mk
@@ -0,0 +1,3 @@
+APP_LOAD_PARAMS += --path "44'/554'"  --path "44'/60'"
+DEFINES += CHAINID_UPCASE=\"TECRATESTNET\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531811
+APPNAME = "TecraTestnet"
\ No newline at end of file
diff --git a/tests/speculos/.gitignore b/tests/speculos/.gitignore
new file mode 100644
index 000000000..94026aa28
--- /dev/null
+++ b/tests/speculos/.gitignore
@@ -0,0 +1,25 @@
+__pycache__/
+*.py[cod]
+*$py.class
+
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# generated by pip
+pip-wheel-metadata/
+
+# pytest debug logs generated via --debug
+pytestdebug.log
+.cache
+.pytest_cache
+.mypy_cache
+.coverage
+.coverage.*
+coverage.xml
\ No newline at end of file
diff --git a/tests/speculos/README.md b/tests/speculos/README.md
new file mode 100644
index 000000000..c3bb346cb
--- /dev/null
+++ b/tests/speculos/README.md
@@ -0,0 +1,50 @@
+# Speculos functional tests
+
+These tests are implemented in Python with the `SpeculosClient` interface which allows easy execution on the [Speculos](https://github.com/LedgerHQ/speculos) emulator.
+
+## Requirements
+
+- [python >= 3.8](https://www.python.org/downloads/)
+- [pip](https://pip.pypa.io/en/stable/installation/)
+
+### Dependencies
+Python dependencies are listed in [requirements.txt](requirements.txt)
+
+```shell
+python3 -m pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt
+```
+> The extra index allows to fetch the latest version of Speculos.
+
+## Usage
+
+### Compilation app
+
+Go to the root of the repository:
+```sh
+make DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOX_SDK
+mv bin/app.elf tests/speculos/<some name>.elf
+```
+
+Given the requirements are installed, just do (by default command):
+
+```
+cd tests/speculos/
+pytest
+```
+
+### Custom options
+- **--model:**  "nanos", "nanox", "nanosp" | default: "nanos"
+- **--display:** "qt", "headless"          | default: "qt"
+- **--path:** the path of the binary app   | default: path of makefile compilation
+
+## Example
+
+With `nanox` binary app:
+```sh
+# the --path is variable to where you put your binary
+
+pytest --model nanox --path ./elfs/nanox.elf
+
+# Execute specific test:
+pytest --model nanox --path ./elfs/nanox.elf test_pubkey_cmd.py
+```
\ No newline at end of file
diff --git a/tests/speculos/conftest.py b/tests/speculos/conftest.py
new file mode 100644
index 000000000..b10f7a684
--- /dev/null
+++ b/tests/speculos/conftest.py
@@ -0,0 +1,41 @@
+from pathlib import Path
+import pytest
+
+from speculos.client import SpeculosClient
+
+from ethereum_client.ethereum_cmd import EthereumCommand
+
+
+SCRIPT_DIR = Path(__file__).absolute().parent
+API_URL = "http://127.0.0.1:5000"
+
+VERSION = {"nanos": "2.1", "nanox": "2.0.2", "nanosp": "1.0.3"}
+
+
+def pytest_addoption(parser):
+    # nanos, nanox, nanosp
+    parser.addoption("--model", action="store", default="nanos")
+    # qt: default, requires a X server
+    # headless: nothing is displayed
+    parser.addoption("--display", action="store", default="qt")
+
+    path: str = SCRIPT_DIR.parent.parent / "bin" / "app.elf"
+    parser.addoption("--path", action="store", default=path)
+
+@pytest.fixture()
+def client(pytestconfig):
+    file_path = pytestconfig.getoption("path")
+    model = pytestconfig.getoption("model")
+
+    args = ['--log-level', 'speculos:DEBUG','--model', model, '--display', pytestconfig.getoption("display"), '--sdk', VERSION[model]]
+    with SpeculosClient(app=str(file_path), args=args) as client:
+        yield client
+
+
+@pytest.fixture()
+def cmd(client, pytestconfig):
+    yield EthereumCommand(
+        client=client,
+        debug=True,
+        model=pytestconfig.getoption("model"),
+    )
diff --git a/tests/speculos/docs/README.md b/tests/speculos/docs/README.md
new file mode 100644
index 000000000..eb6df7138
--- /dev/null
+++ b/tests/speculos/docs/README.md
@@ -0,0 +1,133 @@
+# Documentation of Ethereum's client test
+
+```sh
+.
+├── conftest.py                                     # Configuration for pytest
+├── ethereum_client                                 # All utils of client test
+│   ├── ethereum_cmd_builder.py                     # Creation of apdu to send
+│   ├── ethereum_cmd.py                             # Send Apdu and parsing of response
+│   ├── exception
+│   │   ├── device_exception.py
+│   │   └── errors.py
+│   ├── plugin.py                                   # Creation of content apdu which manage plugin, erc20Information, provide nft information
+│   ├── transaction.py                              # Creation of content apdu which manage personal tx, transaction, eip712
+│   └── utils.py
+├── requirements.txt
+├── screenshots                                     # All screenshot of nanoS,X,SP for compare in tests
+├── setup.cfg
+
+# ========= All Tests =========
+├── test_configuration_cmd.py
+├── test_eip1559.py
+├── test_eip191.py
+├── test_eip2930.py
+├── test_eip712.py
+├── test_erc1155.py
+├── test_erc20information.py
+├── test_erc721.py
+├── test_pubkey_cmd.py
+└── test_sign_cmd.py
+```
+
+## Ethereum_client
+
+### Ethereum_cmd_builder
+```py
+def chunked(size, source)
+
+class EthereumCommandBuilder:
+    # Creation of the apdu
+    def get_configuration(self) -> bytes:
+    def set_plugin(self, plugin: Plugin) -> bytes:
+    def provide_nft_information(self, plugin: Plugin) -> bytes:
+    def provide_erc20_token_information(self, info: ERC20Information):
+    def get_public_key(self, bip32_path: str, display: bool = False) -> bytes:
+    def perform_privacy_operation(self, bip32_path: str, display: bool, shared_secret: bool) -> bytes:
+    def simple_sign_tx(self, bip32_path: str, transaction: Transaction) -> bytes:
+    def sign_eip712(self, bip32_path: str, transaction: EIP712) -> bytes:
+    def personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction) -> Tuple[bool,bytes]:
+```
+
+### Ethereum_cmd
+```py
+class EthereumCommand:
+    # Sending apdu and parsing the response in the right form
+    def get_configuration(self) -> Tuple[int, int, int, int]:
+    def set_plugin(self, plugin: Plugin):
+    def provide_nft_information(self, plugin: Plugin):
+    def provide_erc20_token_information(self, info: ERC20Information):
+    def get_public_key(self, bip32_path: str, result: List, display: bool = False) -> Tuple[bytes, bytes, bytes]:
+    def perform_privacy_operation(self, bip32_path: str, result: List, display: bool = False, shared_secret: bool = False) -> Tuple[bytes, bytes, bytes]:
+    def simple_sign_tx(self, bip32_path: str, transaction: Transaction, result: List = list()) -> None:
+    def sign_eip712(self, bip32_path: str, transaction: EIP712, result: List = list()) -> None:
+    def personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction, result: List = list()) -> None:
+    
+
+    # Allows to send an apdu without return of speculos
+    def send_apdu(self, apdu: bytes) -> bytes:
+    # Allows to send an apdu with return of speculos
+    def send_apdu_context(self, apdu: bytes, result: List = list()) -> bytes:
+    
+```
+
+### Utils
+```py
+def save_screenshot(cmd, path: str):
+def compare_screenshot(cmd, path: str):
+def parse_sign_response(response : bytes) -> Tuple[bytes, bytes, bytes]:
+def bip32_path_from_string(path: str) -> List[bytes]:
+def packed_bip32_path_from_string(path: str) -> bytes:
+def write_varint(n: int) -> bytes:
+def read_varint(buf: BytesIO, prefix: Optional[bytes] = None) -> int:
+def read(buf: BytesIO, size: int) -> bytes:
+def read_uint(buf: BytesIO,
+```
+
+## Tests new apdu
+
+If a new instruction is programmed it will be necessary to create 2 new functions.  
+one in `ethereum_cmd_builder` :  
+- Creation of the raw apdu you can find some examples in this same file
+  
+and one in `ethereum_cmd`:  
+- Send the apdu to speculos and parse the answer in a `list` named result you can find some examples in this same file
+
+## Example for write new tests
+
+To send several apdu and get the return 
+
+```py
+FIRST = bytes.fromhex("{YourAPDU}")
+SECOND = bytes.fromhex("{YourAPDU}")
+
+def test_multiple_raw_apdu(cmd):
+    result: list = []
+
+    cmd.send_apdu(FIRST)
+    with cmd.send_apdu_context(SECOND, result) as ex:
+        sleep(0.5)
+        # Here your code for press button and compare screen if you want
+
+    response: bytes = result[0] # response returning
+    # Here you function to parse response of some code
+    v, r, s = parse_sign_response(response)
+
+    # And here assertion of your tests
+    assert v == 0x25 # 37
+    assert r.hex() == "68ba082523584adbfc31d36d68b51d6f209ce0838215026bf1802a8f17dcdff4"
+    assert s.hex() == "7c92908fa05c8bc86507a3d6a1c8b3c2722ee01c836d89a61df60c1ab0b43fff"
+```
+
+To test an error
+
+```py
+def test_some_error(cmd):
+    result: list = []
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+        # With an function in ethereum_cmd
+        with cmd.send_apdu_context(bytes.fromhex("{YourAPDU}"), result) as ex:
+            pass
+        assert error.args[0] == '0x6a80'
+```
+
diff --git a/tests/speculos/ethereum_client/__init__.py b/tests/speculos/ethereum_client/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/speculos/ethereum_client/ethereum_cmd.py b/tests/speculos/ethereum_client/ethereum_cmd.py
new file mode 100644
index 000000000..a13a817cf
--- /dev/null
+++ b/tests/speculos/ethereum_client/ethereum_cmd.py
@@ -0,0 +1,226 @@
+from ast import List
+from contextlib import contextmanager
+import struct
+from time import sleep
+from typing import Tuple
+
+from speculos.client import SpeculosClient, ApduException
+
+from ethereum_client.ethereum_cmd_builder import EthereumCommandBuilder, InsType
+from ethereum_client.exception import DeviceException
+from ethereum_client.transaction import EIP712, PersonalTransaction, Transaction
+from ethereum_client.plugin import ERC20Information, Plugin
+from ethereum_client.utils import parse_sign_response
+
+
+class EthereumCommand:
+    def __init__(self,
+                 client: SpeculosClient,
+                 debug: bool = False,
+                 model: str = "nanos") -> None:
+        self.client = client
+        self.builder = EthereumCommandBuilder(debug=debug)
+        self.debug = debug
+        self.model = model
+    
+    def get_configuration(self) -> Tuple[int, int, int, int]:
+        try:
+            response = self.client._apdu_exchange(
+                self.builder.get_configuration()
+            )  # type: int, bytes
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_VERSION)
+
+        # response = FLAG (1) || MAJOR (1) || MINOR (1) || PATCH (1)
+        assert len(response) == 4
+
+        info, major, minor, patch = struct.unpack(
+            "BBBB",
+            response
+        )  # type: int, int, int
+
+        return info, major, minor, patch
+
+    def set_plugin(self, plugin: Plugin):
+        try:
+            self.client._apdu_exchange(
+                self.builder.set_plugin(plugin=plugin)
+            )
+        
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SET_PLUGIN)
+
+    def provide_nft_information(self, plugin: Plugin):
+        try:
+            self.client._apdu_exchange(
+                self.builder.provide_nft_information(plugin=plugin)
+            )
+
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_PROVIDE_NFT_INFORMATION)
+
+    def provide_erc20_token_information(self, info: ERC20Information):
+        try:
+            self.client._apdu_exchange(
+                self.builder.provide_erc20_token_information(info=info)
+            )
+
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_PROVIDE_ERC20)
+
+
+    @contextmanager
+    def get_public_key(self, bip32_path: str, result: List, display: bool = False) -> Tuple[bytes, bytes, bytes]:
+        try:
+            chunk: bytes = self.builder.get_public_key(bip32_path=bip32_path, display=display)
+
+            with self.client.apdu_exchange_nowait(cla=chunk[0], ins=chunk[1],
+                                                          p1=chunk[2], p2=chunk[3],
+                                                          data=chunk[5:]) as exchange:
+                yield exchange
+                response: bytes = exchange.receive()
+                
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_PUBLIC_KEY)
+
+        # response = pub_key_len (1) ||
+        #            pub_key (var) ||
+        #            chain_code_len (1) ||
+        #            chain_code (var)
+        offset: int = 0
+
+        pub_key_len: int = response[offset]
+        offset += 1
+
+        uncompressed_addr_len: bytes = response[offset:offset + pub_key_len]
+        offset += pub_key_len
+        
+        eth_addr_len: int = response[offset]
+        offset += 1
+        
+        eth_addr: bytes = response[offset:offset + eth_addr_len]
+        offset += eth_addr_len
+
+        chain_code: bytes = response[offset:]
+
+        assert len(response) == 1 + pub_key_len + 1 + eth_addr_len + 32 # 32 -> chain_code_len
+        
+        result.append(uncompressed_addr_len)
+        result.append(eth_addr)
+        result.append(chain_code)
+
+
+    @contextmanager
+    def perform_privacy_operation(self, bip32_path: str, result: List, display: bool = False, shared_secret: bool = False) -> Tuple[bytes, bytes, bytes]:
+        try:
+            chunk: bytes = self.builder.perform_privacy_operation(bip32_path=bip32_path, display=display, shared_secret=shared_secret)
+
+            with self.client.apdu_exchange_nowait(cla=chunk[0], ins=chunk[1],
+                                                          p1=chunk[2], p2=chunk[3],
+                                                          data=chunk[5:]) as exchange:
+                yield exchange
+                response: bytes = exchange.receive()
+                
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_PERFORM_PRIVACY_OPERATION)
+
+        # response = Public encryption key or shared secret	(32)
+        assert len(response) == 32
+
+        result.append(response)
+
+    def send_apdu(self, apdu: bytes) -> bytes:
+        try:
+            self.client.apdu_exchange(cla=apdu[0], ins=apdu[1],
+                                        p1=apdu[2], p2=apdu[3],
+                                        data=apdu[5:])
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX)
+
+    @contextmanager
+    def send_apdu_context(self, apdu: bytes, result: List = list()) -> bytes:
+        try:
+
+            with self.client.apdu_exchange_nowait(cla=apdu[0], ins=apdu[1],
+                                                    p1=apdu[2], p2=apdu[3],
+                                                    data=apdu[5:]) as exchange:
+                yield exchange
+                result.append(exchange.receive())
+            
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX)
+
+
+
+    @contextmanager
+    def simple_sign_tx(self, bip32_path: str, transaction: Transaction, result: List = list()) -> None:
+        try:
+            chunk: bytes = self.builder.simple_sign_tx(bip32_path=bip32_path, transaction=transaction)
+
+            with self.client.apdu_exchange_nowait(cla=chunk[0], ins=chunk[1],
+                                                          p1=chunk[2], p2=chunk[3],
+                                                          data=chunk[5:]) as exchange:
+                yield exchange
+                response: bytes = exchange.receive()
+                
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX)
+
+        # response = V (1) || R (32) || S (32)
+        assert len(response) == 65
+        v, r, s = parse_sign_response(response)
+        
+        result.append(v)
+        result.append(r)
+        result.append(s)
+
+
+    @contextmanager
+    def sign_eip712(self, bip32_path: str, transaction: EIP712, result: List = list()) -> None:
+        try:
+            chunk: bytes = self.builder.sign_eip712(bip32_path=bip32_path, transaction=transaction)
+
+            with self.client.apdu_exchange_nowait(cla=chunk[0], ins=chunk[1],
+                                                          p1=chunk[2], p2=chunk[3],
+                                                          data=chunk[5:]) as exchange:
+                yield exchange
+                response: bytes = exchange.receive()
+                
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_EIP712)
+
+        # response = V (1) || R (32) || S (32)
+        assert len(response) == 65
+        v, r, s = parse_sign_response(response)
+        
+        result.append(v)
+        result.append(r)
+        result.append(s)
+
+
+    @contextmanager
+    def personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction, result: List = list()) -> None:
+        try:
+            for islast_apdu, apdu in self.builder.personal_sign_tx(bip32_path=bip32_path, transaction=transaction):
+                if islast_apdu:
+                    with self.client.apdu_exchange_nowait(cla=apdu[0], ins=apdu[1],
+                                                    p1=apdu[2], p2=apdu[3],
+                                                    data=apdu[5:]) as exchange:
+                        # the "yield" here allows to wait for a button interaction (click right, left, both)
+                        yield exchange
+                        response: bytes = exchange.receive()
+                else:
+                    self.send_apdu(apdu)
+                
+        except ApduException as error:
+            raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX)
+
+         # response = V (1) || R (32) || S (32)
+        v, r, s = parse_sign_response(response)
+        
+        result.append(v)
+        result.append(r)
+        result.append(s)
+
+
+
diff --git a/tests/speculos/ethereum_client/ethereum_cmd_builder.py b/tests/speculos/ethereum_client/ethereum_cmd_builder.py
new file mode 100644
index 000000000..f2f721e2d
--- /dev/null
+++ b/tests/speculos/ethereum_client/ethereum_cmd_builder.py
@@ -0,0 +1,293 @@
+import enum
+import logging
+import struct
+from typing import List, Tuple, Union, Iterator, cast
+
+from ethereum_client.transaction import EIP712, PersonalTransaction, Transaction
+from ethereum_client.plugin import ERC20Information, Plugin
+from ethereum_client.utils import packed_bip32_path_from_string
+
+MAX_APDU_LEN: int = 255
+
+def chunked(size, source):
+    for i in range(0, len(source), size):
+        yield source[i:i+size]
+
+def chunkify(data: bytes, chunk_len: int) -> Iterator[Tuple[bool, bytes]]:
+    size: int = len(data)
+
+    if size <= chunk_len:
+        yield True, data
+        return
+
+    chunk: int = size // chunk_len
+    remaining: int = size % chunk_len
+    offset: int = 0
+
+    for i in range(chunk):
+        yield False, data[offset:offset + chunk_len]
+        offset += chunk_len
+
+    if remaining:
+        yield True, data[offset:]
+
+class InsType(enum.IntEnum):
+    INS_GET_PUBLIC_KEY          = 0x02
+    INS_SIGN_TX                 = 0x04
+    INS_GET_CONFIGURATION       = 0x06
+    INS_SIGN_PERSONAL_TX        = 0x08
+    INS_PROVIDE_ERC20           = 0x0A
+    INS_SIGN_EIP712             = 0x0c
+    INS_ETH2_GET_PUBLIC_KEY     = 0x0E
+    INS_SET_ETH2_WITHDRAWAL     = 0x10
+    INS_SET_EXTERNAL_PLUGIN     = 0x12
+    INS_PROVIDE_NFT_INFORMATION = 0x14
+    INS_SET_PLUGIN              = 0x16
+    INS_PERFORM_PRIVACY_OPERATION = 0x18
+
+
+class EthereumCommandBuilder:
+    """APDU command builder for the Boilerplate application.
+
+    Parameters
+    ----------
+    debug: bool
+        Whether you want to see logging or not.
+
+    Attributes
+    ----------
+    debug: bool
+        Whether you want to see logging or not.
+
+    """
+    CLA: int = 0xE0
+
+    def __init__(self, debug: bool = False):
+        """Init constructor."""
+        self.debug = debug
+
+    def serialize(self,
+                  cla: int,
+                  ins: Union[int, enum.IntEnum],
+                  p1: int = 0,
+                  p2: int = 0,
+                  cdata: bytes = b"") -> bytes:
+        """Serialize the whole APDU command (header + data).
+
+        Parameters
+        ----------
+        cla : int
+            Instruction class: CLA (1 byte)
+        ins : Union[int, IntEnum]
+            Instruction code: INS (1 byte)
+        p1 : int
+            Instruction parameter 1: P1 (1 byte).
+        p2 : int
+            Instruction parameter 2: P2 (1 byte).
+        cdata : bytes
+            Bytes of command data.
+
+        Returns
+        -------
+        bytes
+            Bytes of a complete APDU command.
+
+        """
+        ins = cast(int, ins.value) if isinstance(ins, enum.IntEnum) else cast(int, ins)
+
+        header: bytes = struct.pack("BBBBB",
+                                    cla,
+                                    ins,
+                                    p1,
+                                    p2,
+                                    len(cdata))  # add Lc to APDU header
+
+        if self.debug:
+            logging.info("header: %s", header.hex())
+            logging.info("cdata:  %s", cdata.hex())
+
+        return header + cdata
+
+    def get_configuration(self) -> bytes:
+        """Command builder for GET_CONFIGURATON
+
+        Returns
+        -------
+        bytes
+            APDU command for GET_CONFIGURATON
+
+        """
+        return self.serialize(cla=self.CLA,
+                              ins=InsType.INS_GET_CONFIGURATION,
+                              p1=0x00,
+                              p2=0x00,
+                              cdata=b"")
+
+    def _same_header_builder(self, data: Union[Plugin, ERC20Information], ins: int) -> bytes:
+        return self.serialize(cla=self.CLA,
+                              ins=ins,
+                              p1=0x00,
+                              p2=0x00,
+                              cdata=data.serialize())
+
+    def set_plugin(self, plugin: Plugin) -> bytes:
+        return self._same_header_builder(plugin, InsType.INS_SET_PLUGIN)
+
+    def provide_nft_information(self, plugin: Plugin) -> bytes:
+        return self._same_header_builder(plugin, InsType.INS_PROVIDE_NFT_INFORMATION)
+
+    def provide_erc20_token_information(self, info: ERC20Information):
+        return self._same_header_builder(info, InsType.INS_PROVIDE_ERC20)
+
+    def get_public_key(self, bip32_path: str, display: bool = False) -> bytes:
+        """Command builder for GET_PUBLIC_KEY.
+
+        Parameters
+        ----------
+        bip32_path: str
+            String representation of BIP32 path.
+        display : bool
+            Whether you want to display the address on the device.
+
+        Returns
+        -------
+        bytes
+            APDU command for GET_PUBLIC_KEY.
+
+        """
+        cdata = packed_bip32_path_from_string(bip32_path)
+          
+        return self.serialize(cla=self.CLA,
+                              ins=InsType.INS_GET_PUBLIC_KEY,
+                              p1=0x01 if display else 0x00,
+                              p2=0x01,
+                              cdata=cdata)
+
+    def perform_privacy_operation(self, bip32_path: str, display: bool, shared_secret: bool) -> bytes:
+        """Command builder for INS_PERFORM_PRIVACY_OPERATION.
+
+        Parameters
+        ----------
+        bip32_path : str
+            String representation of BIP32 path.
+        Third party public key on Curve25519 : 32 bytes
+            Optionnal if returning the shared secret
+        
+        """
+        cdata = packed_bip32_path_from_string(bip32_path)
+        
+        return self.serialize(cla=self.CLA,
+                              ins=InsType.INS_PERFORM_PRIVACY_OPERATION,
+                              p1=0x01 if display else 0x00,
+                              p2=0x01 if shared_secret else 0x00,
+                              cdata=cdata)
+
+
+    def simple_sign_tx(self, bip32_path: str, transaction: Transaction) -> bytes:
+        """Command builder for INS_SIGN_TX.
+
+        Parameters
+        ----------
+        bip32_path : str
+            String representation of BIP32 path.
+        transaction : Transaction
+            Representation of the transaction to be signed.
+
+        Yields
+        -------
+        bytes
+            APDU command chunk for INS_SIGN_TX.
+
+        """
+        cdata = packed_bip32_path_from_string(bip32_path)
+        
+        tx: bytes = transaction.serialize()
+
+        cdata = cdata + tx
+
+        return self.serialize(cla=self.CLA,
+                              ins=InsType.INS_SIGN_TX,
+                              p1=0x00,
+                              p2=0x00,
+                              cdata=cdata)
+
+    def sign_eip712(self, bip32_path: str, transaction: EIP712) -> bytes:
+        """Command builder for INS_SIGN_EIP712.
+
+        Parameters
+        ----------
+        bip32_path : str
+            String representation of BIP32 path.
+        transaction : EIP712
+            Domain hash  -> 32 bytes
+            Message hash -> 32 bytes
+
+        Yields
+        -------
+        bytes
+            APDU command chunk for INS_SIGN_EIP712.
+
+        """
+        cdata = packed_bip32_path_from_string(bip32_path)
+
+        
+        tx: bytes = transaction.serialize()
+
+        cdata = cdata + tx
+
+        return self.serialize(cla=self.CLA,
+                              ins=InsType.INS_SIGN_EIP712,
+                              p1=0x00,
+                              p2=0x00,
+                              cdata=cdata)
+
+    def personal_sign_tx(self, bip32_path: str, transaction: PersonalTransaction) -> Tuple[bool,bytes]:
+        """Command builder for INS_SIGN_PERSONAL_TX.
+
+        Parameters
+        ----------
+        bip32_path : str
+            String representation of BIP32 path.
+        transaction : Transaction
+            Representation of the transaction to be signed.
+
+        Yields
+        -------
+        bytes
+            APDU command chunk for INS_SIGN_PERSONAL_TX.
+
+        """
+
+        cdata = packed_bip32_path_from_string(bip32_path)
+        
+        tx: bytes = transaction.serialize()
+
+        cdata = cdata + tx
+        last_chunk = len(cdata) // MAX_APDU_LEN
+        
+        # The generator allows to send apdu frames because we can't send an apdu > 255
+        for i, (chunk) in enumerate(chunked(MAX_APDU_LEN, cdata)):
+            if i == 0 and i == last_chunk:
+                yield True, self.serialize(cla=self.CLA,
+                         ins=InsType.INS_SIGN_PERSONAL_TX,
+                         p1=0x00,
+                         p2=0x00,
+                         cdata=chunk)
+            elif i == 0:
+                yield False, self.serialize(cla=self.CLA,
+                         ins=InsType.INS_SIGN_PERSONAL_TX,
+                         p1=0x00,
+                         p2=0x00,
+                         cdata=chunk)
+            elif i == last_chunk:
+                yield True, self.serialize(cla=self.CLA,
+                         ins=InsType.INS_SIGN_PERSONAL_TX,
+                         p1=0x80,
+                         p2=0x00,
+                         cdata=chunk)
+            else:
+                yield False, self.serialize(cla=self.CLA,
+                         ins=InsType.INS_SIGN_PERSONAL_TX,
+                         p1=0x80,
+                         p2=0x00,
+                         cdata=chunk)
\ No newline at end of file
diff --git a/tests/speculos/ethereum_client/exception/__init__.py b/tests/speculos/ethereum_client/exception/__init__.py
new file mode 100644
index 000000000..acb2bb8c0
--- /dev/null
+++ b/tests/speculos/ethereum_client/exception/__init__.py
@@ -0,0 +1,35 @@
+from .device_exception import DeviceException
+from .errors import (UnknownDeviceError,
+                     DenyError,
+                     WrongP1P2Error,
+                     WrongDataLengthError,
+                     InsNotSupportedError,
+                     ClaNotSupportedError,
+                     WrongResponseLengthError,
+                     DisplayBip32PathFailError,
+                     DisplayAddressFailError,
+                     DisplayAmountFailError,
+                     WrongTxLengthError,
+                     TxParsingFailError,
+                     TxHashFail,
+                     BadStateError,
+                     SignatureFailError)
+
+__all__ = [
+    "DeviceException",
+    "DenyError",
+    "UnknownDeviceError",
+    "WrongP1P2Error",
+    "WrongDataLengthError",
+    "InsNotSupportedError",
+    "ClaNotSupportedError",
+    "WrongResponseLengthError",
+    "DisplayBip32PathFailError",
+    "DisplayAddressFailError",
+    "DisplayAmountFailError",
+    "WrongTxLengthError",
+    "TxParsingFailError",
+    "TxHashFail",
+    "BadStateError",
+    "SignatureFailError"
+]
diff --git a/tests/speculos/ethereum_client/exception/device_exception.py b/tests/speculos/ethereum_client/exception/device_exception.py
new file mode 100644
index 000000000..7cd26f23b
--- /dev/null
+++ b/tests/speculos/ethereum_client/exception/device_exception.py
@@ -0,0 +1,38 @@
+import enum
+from typing import Dict, Any, Union
+
+from .errors import *
+
+
+class DeviceException(Exception):  # pylint: disable=too-few-public-methods
+    exc: Dict[int, Any] = {
+        0x6985: DenyError,
+        0x6A86: WrongP1P2Error,
+        0x6A87: WrongDataLengthError,
+        0x6D00: InsNotSupportedError,
+        0x6E00: ClaNotSupportedError,
+        0xB000: WrongResponseLengthError,
+        0xB001: DisplayBip32PathFailError,
+        0xB002: DisplayAddressFailError,
+        0xB003: DisplayAmountFailError,
+        0xB004: WrongTxLengthError,
+        0xB005: TxParsingFailError,
+        0xB006: TxHashFail,
+        0xB007: BadStateError,
+        0xB008: SignatureFailError
+    }
+
+    def __new__(cls,
+                error_code: int,
+                ins: Union[int, enum.IntEnum, None] = None,
+                message: str = ""
+                ) -> Any:
+        error_message: str = (f"Error in {ins!r} command"
+                              if ins else "Error in command")
+
+        if error_code in DeviceException.exc:
+            return DeviceException.exc[error_code](hex(error_code),
+                                                   error_message,
+                                                   message)
+
+        return UnknownDeviceError(hex(error_code), error_message, message)
diff --git a/tests/speculos/ethereum_client/exception/errors.py b/tests/speculos/ethereum_client/exception/errors.py
new file mode 100644
index 000000000..a9a853d50
--- /dev/null
+++ b/tests/speculos/ethereum_client/exception/errors.py
@@ -0,0 +1,58 @@
+class UnknownDeviceError(Exception):
+    pass
+
+
+class DenyError(Exception):
+    pass
+
+
+class WrongP1P2Error(Exception):
+    pass
+
+
+class WrongDataLengthError(Exception):
+    pass
+
+
+class InsNotSupportedError(Exception):
+    pass
+
+
+class ClaNotSupportedError(Exception):
+    pass
+
+
+class WrongResponseLengthError(Exception):
+    pass
+
+
+class DisplayBip32PathFailError(Exception):
+    pass
+
+
+class DisplayAddressFailError(Exception):
+    pass
+
+
+class DisplayAmountFailError(Exception):
+    pass
+
+
+class WrongTxLengthError(Exception):
+    pass
+
+
+class TxParsingFailError(Exception):
+    pass
+
+
+class TxHashFail(Exception):
+    pass
+
+
+class BadStateError(Exception):
+    pass
+
+
+class SignatureFailError(Exception):
+    pass
diff --git a/tests/speculos/ethereum_client/plugin.py b/tests/speculos/ethereum_client/plugin.py
new file mode 100644
index 000000000..9274fdecd
--- /dev/null
+++ b/tests/speculos/ethereum_client/plugin.py
@@ -0,0 +1,70 @@
+import string
+from typing import Union
+
+from ethereum_client.utils import write_varint
+
+class ERC20Information:
+    def __init__(self, erc20_ticker: string , addr: Union[str, bytes], nb_decimals: int, chainID: int, sign: str) -> None:
+        self.erc20_ticker: bytes = bytes.fromhex(erc20_ticker)
+        self.addr: bytes = bytes.fromhex(addr[2:]) if isinstance(addr, str) else addr
+        self.nb_decimals: int = nb_decimals
+        self.chainID: int = chainID
+        self.sign: bytes = bytes.fromhex(sign)
+    
+    def serialize(self) -> bytes:
+        return b"".join([
+            write_varint(len(self.erc20_ticker)),
+            self.erc20_ticker,
+
+            self.addr,
+
+            self.nb_decimals.to_bytes(4, byteorder="big"),
+
+            self.chainID.to_bytes(4, byteorder="big"),
+
+            self.sign,
+        ])
+
+class Plugin:
+    """Plugin class
+    Allows to generate an apdu of the SET_PLUGIN command or PROVIDE_NFT_INFORMATION
+
+    PROVIDE_NFT_INFORMATION
+    ----
+     do not define a selector
+
+    """
+    def __init__(self, type: int, version: int, name: str, addr: Union[str, bytes], selector: int = -1, chainID: int = 1, keyID: int = 0, algorithm: int = 1, sign: str = "") -> None:
+        self.type: int = type
+        self.version: int = version
+        self.name: bytes = bytes(name, 'UTF-8')
+        self.addr: bytes = bytes.fromhex(addr[2:]) if isinstance(addr, str) else addr
+        self.selector: int = selector
+        self.chainID: int = chainID
+        self.keyID: int = keyID
+        self.algorithm: int = algorithm
+        self.sign: bytes = bytes.fromhex(sign)
+
+    def serialize(self) -> bytes:
+        return b"".join([
+            self.type.to_bytes(1, byteorder="big"),
+
+            self.version.to_bytes(1, byteorder="big"),
+
+            write_varint(len(self.name)),
+            self.name,
+
+            self.addr,
+
+            b'' if self.selector == -1 else self.selector.to_bytes(4, byteorder="big"),
+
+            self.chainID.to_bytes(8, byteorder="big"),
+
+            self.keyID.to_bytes(1, byteorder="big"),
+
+            self.algorithm.to_bytes(1, byteorder="big"),
+
+            write_varint(len(self.sign)),
+            self.sign,
+
+        ])
\ No newline at end of file
diff --git a/tests/speculos/ethereum_client/transaction.py b/tests/speculos/ethereum_client/transaction.py
new file mode 100644
index 000000000..4c9fe2395
--- /dev/null
+++ b/tests/speculos/ethereum_client/transaction.py
@@ -0,0 +1,96 @@
+from typing import Union
+
+from ethereum_client.utils import write_varint, UINT64_MAX
+
+
+class TransactionError(Exception):
+    pass
+
+EIP2930 = 1
+EIP1559 = 2
+
+class PersonalTransaction:
+    def __init__(self, msg: Union[str, bytes]) -> None:
+        # If you want to send bytes directly you have to put "0x" before the string
+        if msg[0:2] == "0x":
+            self.msg: bytes = bytes.fromhex(msg[2:])
+        else:
+            self.msg: bytes = bytes(msg, "utf-8")
+
+    def serialize(self) -> bytes:
+        return b"".join([
+            len(self.msg).to_bytes(4, byteorder="big"),
+            self.msg,
+        ])
+
+class Transaction:
+    def __init__(self, txType: int, nonce: int, gasPrice: int, gasLimit: int, to: Union[str, bytes], value: int, data: Union[str, bytes] = "", chainID: int = -1) -> None:
+        self.txType: int = txType
+        self.nonce: int = nonce
+        self.gasPrice: int = gasPrice
+        self.gasLimit: int = gasLimit
+        self.to: bytes = bytes.fromhex(to[2:]) if isinstance(to, str) else to
+        self.value: int = value
+        self.data: bytes = bytes(data, "utf-8")
+        self.chainID = b''
+
+        if not (0 <= self.nonce <= UINT64_MAX):
+            raise TransactionError(f"Bad nonce: '{self.nonce}'!")
+
+        if not (0 <= self.value <= UINT64_MAX):
+            raise TransactionError(f"Bad value: '{self.value}'!")
+
+        if len(self.to) != 20:
+            raise TransactionError(f"Bad address: '{self.to}'!")
+
+        self.lenNonce = int((len(hex(self.nonce)) - 1) / 2)
+        self.lenGP = int((len(hex(self.gasPrice)) - 1) / 2)
+        self.lenGL = int((len(hex(self.gasLimit)) - 1) / 2)
+        self.lenValue = int((len(hex(self.value)) - 1) / 2)
+
+        self.lenChainID = int((len(hex(chainID)) - 1) / 2)
+
+        if chainID != -1:
+            self.chainID = b"".join([
+                b'' if self.lenChainID == 1 else (self.lenChainID + 0x80).to_bytes(1, byteorder="big"),
+                chainID.to_bytes(self.lenChainID, byteorder="big"),
+                write_varint(0 + 0x80),
+                write_varint(0 + 0x80),
+            ])
+
+    def serialize(self) -> bytes:
+        return b"".join([
+            self.txType.to_bytes(1, byteorder="big"),
+
+            b'' if self.lenNonce == 1 else write_varint(self.lenNonce + 0x80),
+            self.nonce.to_bytes(self.lenNonce, byteorder="big"),
+
+            write_varint(self.lenGP + 0x80),
+            self.gasPrice.to_bytes(self.lenGP, byteorder="big"),
+
+            write_varint(self.lenGL + 0x80),
+            self.gasLimit.to_bytes(self.lenGL, byteorder="big"),
+
+            write_varint(len(self.to) + 0x80),
+            self.to,
+
+            write_varint(self.lenValue + 0x80),
+            self.value.to_bytes(self.lenValue, byteorder="big"),
+
+            write_varint(len(self.data) + 0x80),
+            self.data,
+
+            self.chainID,
+
+        ])
+
+class EIP712:
+    def __init__(self, domain_hash: str, msg_hash: str) -> None:
+        self.domain_hash = bytes.fromhex(domain_hash)
+        self.msg_hash = bytes.fromhex(msg_hash)
+    
+    def serialize(self) -> bytes:
+        return b"".join([
+            self.domain_hash,
+            self.msg_hash
+        ])
\ No newline at end of file
diff --git a/tests/speculos/ethereum_client/utils.py b/tests/speculos/ethereum_client/utils.py
new file mode 100644
index 000000000..be3cdde9b
--- /dev/null
+++ b/tests/speculos/ethereum_client/utils.py
@@ -0,0 +1,115 @@
+from io import BytesIO
+from typing import List, Optional, Literal, Tuple
+import PIL.Image as Image
+
+import speculos.client
+
+UINT64_MAX: int = 18446744073709551615
+UINT32_MAX: int = 4294967295
+UINT16_MAX: int = 65535
+
+# Association tableau si écran nanos ou nanox
+PATH_IMG = {"nanos": "nanos", "nanox": "nanox", "nanosp": "nanox"}
+
+def save_screenshot(cmd, path: str):
+    screenshot = cmd.client.get_screenshot()
+    img = Image.open(BytesIO(screenshot))
+    img.save(path)
+
+
+def compare_screenshot(cmd, path: str):
+    screenshot = cmd.client.get_screenshot()
+    assert speculos.client.screenshot_equal(path, BytesIO(screenshot))
+
+
+def parse_sign_response(response : bytes) -> Tuple[bytes, bytes, bytes]:
+    assert len(response) == 65
+
+    offset: int = 0
+
+    v: bytes = response[offset]
+    offset += 1
+
+    r: bytes = response[offset:offset + 32]
+    offset += 32
+
+    s: bytes = response[offset:]
+
+    return (v, r, s)
+
+
+def bip32_path_from_string(path: str) -> List[bytes]:
+    splitted_path: List[str] = path.split("/")
+
+    if not splitted_path:
+        raise Exception(f"BIP32 path format error: '{path}'")
+
+    if "m" in splitted_path and splitted_path[0] == "m":
+        splitted_path = splitted_path[1:]
+
+    return [int(p).to_bytes(4, byteorder="big") if "'" not in p
+            else (0x80000000 | int(p[:-1])).to_bytes(4, byteorder="big")
+            for p in splitted_path]
+
+
+def packed_bip32_path_from_string(path: str) -> bytes:
+    bip32_paths = bip32_path_from_string(path)
+    
+    return b"".join([
+            len(bip32_paths).to_bytes(1, byteorder="big"),
+            *bip32_paths
+        ])
+
+
+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")
+
+    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}'!")
+
+    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"Cant 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)
diff --git a/tests/speculos/old_test_eip191.py b/tests/speculos/old_test_eip191.py
new file mode 100644
index 000000000..d24ad0b7c
--- /dev/null
+++ b/tests/speculos/old_test_eip191.py
@@ -0,0 +1,209 @@
+from time import sleep
+
+import pytest
+
+import ethereum_client
+from ethereum_client.utils import compare_screenshot, compare_screenshot, parse_sign_response, save_screenshot, PATH_IMG
+from ethereum_client.transaction import PersonalTransaction
+
+def test_personal_sign_metamask(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0/0"
+    transaction = PersonalTransaction(
+        msg="Example `personal_sign` message"
+    )
+
+    with cmd.personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message 1/2, 2/2
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00003.png")
+            cmd.client.press_and_release('both')
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_metamask/00002.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x1c # 28
+    assert r.hex() == "916099cf0d9c21911c85f0770a47a9696a8189e78c259cf099749748c507baae"
+    assert s.hex() == "0d72234bc0ac2e94c5f7a5f4f9cd8610a52be4ea55515a85b9703f1bb158415c"
+ 
+def test_personal_sign_reject(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0/0"
+    transaction = PersonalTransaction(
+        msg="This is an reject sign"
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+        with cmd.personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            sleep(0.5)
+
+            if cmd.model == "nanos":
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Message 1/2, 2/2
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00001.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00002.png")
+                cmd.client.press_and_release('right')
+
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00003.png")
+                cmd.client.press_and_release('right')
+
+                # Cancel signature
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00004.png")
+                cmd.client.press_and_release('both')
+
+            if cmd.model == "nanox" or cmd.model == "nanosp":
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Message
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00001.png")
+                cmd.client.press_and_release('right')
+
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00002.png")
+                cmd.client.press_and_release('right')
+
+                # Cancel signature
+                compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_reject/00003.png")
+                cmd.client.press_and_release('both')
+        assert error.args[0] == '0x6985'
+
+def test_personal_sign_non_ascii(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0/0"
+    transaction = PersonalTransaction(
+        msg="0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658"
+    )
+
+    with cmd.personal_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message 1/4, 2/4, 3/4, 4/4
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00005.png")
+            cmd.client.press_and_release('both')
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message 1/2, 2/2
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_non_ascii/00003.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x1c # 28
+    assert r.hex() == "64bdbdb6959425445d00ff2536a7018d2dce904e1f7475938fe4221c3c72500c"
+    assert s.hex() == "7c9208e99b6b9266a73aae17b73472d06499746edec34fd47a9dab42f06f2e42"
+
+def test_personal_sign_opensea(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0/0"
+    transaction = PersonalTransaction(
+        msg="Welcome to OpenSea!\n\nClick to sign in and accept the OpenSea Terms of Service: https://opensea.io/tos\n\nThis request will not trigger a blockchain transaction or cost any gas fees.\n\nYour authentication status will reset after 24 hours.\n\nWallet address:\n0x9858effd232b4033e47d90003d41ec34ecaeda94\n\nNonce:\n2b02c8a0-f74f-4554-9821-a28054dc9121"
+    )
+
+    with cmd.personal_sign_tx(bip32_path, transaction, result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message 1/5, 2/5, 3/5, 4/5, 5/5
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00006.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Message 1/5, 2/5, 3/5, 4/5, 5/5
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip191/{PATH_IMG[cmd.model]}/personal_sign_opensea/00006.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x1c # 28
+    assert r.hex() == "61a68c986f087730d2f6ecf89d6d1e48ab963ac461102bb02664bc05c3db75bb"
+    assert s.hex() == "5714729ef441e097673a7b29a681e97f6963d875eeed2081f26b0b6686cd2bd2"
diff --git a/tests/speculos/requirements.txt b/tests/speculos/requirements.txt
new file mode 100644
index 000000000..2744c3552
--- /dev/null
+++ b/tests/speculos/requirements.txt
@@ -0,0 +1,5 @@
+speculos
+pytest>=6.1.1,<7.0.0
+ledgercomm>=1.1.0,<1.2.0
+ecdsa>=0.16.1,<0.17.0
+pysha3>=1.0.0,<2.0.0
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00000.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00000.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00000.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00000.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00001.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00001.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00001.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00001.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00002.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00002.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00002.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00003.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00003.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00003.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00004.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00004.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00004.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00005.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00005.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00005.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00006.png b/tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00006.png
rename to tests/speculos/screenshots/eip1559/nanos/sign_eip_1559/00006.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00000.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00000.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00000.png
rename to tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00000.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00001.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00001.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00001.png
rename to tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00001.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00002.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00002.png
rename to tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00002.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00003.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00003.png
rename to tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00004.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00004.png
rename to tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00004.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00000.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00000.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00000.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00001.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00001.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00001.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00002.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00002.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00002.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00003.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00003.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_metamask/00003.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00000.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00000.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00000.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00001.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00001.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00001.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00002.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00002.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00002.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00003.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00003.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00003.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00004.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00004.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00004.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00005.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00005.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00005.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_non_ascii/00005.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00000.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00000.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00000.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00001.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00001.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00001.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00002.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00002.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00002.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00002.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00003.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00003.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00003.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00003.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00004.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00004.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00004.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00005.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00005.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00005.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00005.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00006.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00006.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00006.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_opensea/00006.png
diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png
new file mode 100644
index 000000000..ab16f62bf
Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00000.png differ
diff --git a/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png
new file mode 100644
index 000000000..6603459d1
Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00001.png differ
diff --git a/tests/snapshots/nanos_eip191_nonascii/00005.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00002.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00005.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00002.png
diff --git a/tests/snapshots/nanos_eip191_metamask/00004.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00003.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00004.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00003.png
diff --git a/tests/snapshots/nanos_eip191_nonascii/00006.png b/tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00004.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00006.png
rename to tests/speculos/screenshots/eip191/nanos/personal_sign_reject/00004.png
diff --git a/tests/snapshots/nanox_eip191_metamask/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00000.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00000.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00000.png
diff --git a/tests/snapshots/nanox_eip191_metamask/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00001.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00001.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00001.png
diff --git a/tests/snapshots/nanox_eip191_metamask/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00002.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00002.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_metamask/00002.png
diff --git a/tests/snapshots/nanox_eip191_nonascii/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00000.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00000.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00000.png
diff --git a/tests/snapshots/nanox_eip191_nonascii/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00001.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00001.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00001.png
diff --git a/tests/snapshots/nanox_eip191_nonascii/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00002.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00002.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00002.png
diff --git a/tests/snapshots/nanox_eip191_nonascii/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00003.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00003.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_non_ascii/00003.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00000.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00000.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00000.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00001.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00001.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00001.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00002.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00002.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00002.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00002.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00003.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00003.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00003.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00004.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00004.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00004.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00004.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00005.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00005.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00005.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00005.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00006.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00006.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00006.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_opensea/00006.png
diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png
new file mode 100644
index 000000000..1b271542d
Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00000.png differ
diff --git a/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png
new file mode 100644
index 000000000..717f3a5ba
Binary files /dev/null and b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00001.png differ
diff --git a/tests/snapshots/nanox_eip191_metamask/00004.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00002.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00004.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00002.png
diff --git a/tests/snapshots/nanox_eip191_metamask/00003.png b/tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00003.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00003.png
rename to tests/speculos/screenshots/eip191/nanox/personal_sign_reject/00003.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00000.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00000.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00000.png
rename to tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00000.png
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00001.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00001.png
new file mode 100644
index 000000000..68b7cb31d
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00001.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00002.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00002.png
new file mode 100644
index 000000000..304f99e5f
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00002.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00003.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00003.png
new file mode 100644
index 000000000..cdb80b744
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00003.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00004.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00004.png
new file mode 100644
index 000000000..39f91a14a
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00004.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00005.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00005.png
new file mode 100644
index 000000000..2f61fc967
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00005.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00006.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00006.png
new file mode 100644
index 000000000..493527e1d
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00006.png differ
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00007.png b/tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00007.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00007.png
rename to tests/speculos/screenshots/eip2930/nanos/sign_eip_2930/00007.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00000.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00000.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00000.png
rename to tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00000.png
diff --git a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00001.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00001.png
new file mode 100644
index 000000000..1a0c6c3d0
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00001.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00002.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00002.png
new file mode 100644
index 000000000..8588465ac
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00002.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00003.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00003.png
new file mode 100644
index 000000000..b2dc741ab
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00003.png differ
diff --git a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png
new file mode 100644
index 000000000..f1733ce44
Binary files /dev/null and b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png differ
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00005.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00005.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00005.png
rename to tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00005.png
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00000.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00000.png
new file mode 100644
index 000000000..910bc4302
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00000.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00001.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00001.png
new file mode 100644
index 000000000..1492bd7a1
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00001.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00002.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00002.png
new file mode 100644
index 000000000..f6dba7ed9
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00002.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00003.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00003.png
new file mode 100644
index 000000000..21193e007
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00003.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00004.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00004.png
new file mode 100644
index 000000000..45c88a315
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00004.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00005.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00005.png
new file mode 100644
index 000000000..a512c884e
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00005.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00006.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00006.png
new file mode 100644
index 000000000..489127ffa
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00006.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00007.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00007.png
new file mode 100644
index 000000000..61bcb2d48
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00007.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00008.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00008.png
new file mode 100644
index 000000000..326560118
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00008.png differ
diff --git a/tests/snapshots/nanos_eip191_nonascii/00007.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00009.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00007.png
rename to tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg/00009.png
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00000.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00000.png
new file mode 100644
index 000000000..910bc4302
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00000.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00001.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00001.png
new file mode 100644
index 000000000..1492bd7a1
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00001.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00002.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00002.png
new file mode 100644
index 000000000..f6dba7ed9
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00002.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00003.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00003.png
new file mode 100644
index 000000000..21193e007
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00003.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00004.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00004.png
new file mode 100644
index 000000000..45c88a315
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00004.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00005.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00005.png
new file mode 100644
index 000000000..a512c884e
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00005.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00006.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00006.png
new file mode 100644
index 000000000..489127ffa
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00006.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00007.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00007.png
new file mode 100644
index 000000000..61bcb2d48
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00007.png differ
diff --git a/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00008.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00008.png
new file mode 100644
index 000000000..326560118
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00008.png differ
diff --git a/tests/snapshots/nanos_eip191_opensea/00008.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00009.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00008.png
rename to tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00009.png
diff --git a/tests/snapshots/nanos_eip191_opensea/00007.png b/tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00010.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00007.png
rename to tests/speculos/screenshots/eip712/nanos/sign_eip_712_hashed_msg_reject/00010.png
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00000.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00000.png
new file mode 100644
index 000000000..00a89fd69
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00000.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00001.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00001.png
new file mode 100644
index 000000000..dfd24f466
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00001.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00002.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00002.png
new file mode 100644
index 000000000..542bf198f
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00002.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00003.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00003.png
new file mode 100644
index 000000000..ae1ff79c1
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00003.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00004.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00004.png
new file mode 100644
index 000000000..034e96f49
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00004.png differ
diff --git a/tests/snapshots/nanox_eip191_nonascii/00005.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00005.png
rename to tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00000.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00000.png
new file mode 100644
index 000000000..00a89fd69
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00000.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00001.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00001.png
new file mode 100644
index 000000000..dfd24f466
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00001.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00002.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00002.png
new file mode 100644
index 000000000..542bf198f
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00002.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00003.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00003.png
new file mode 100644
index 000000000..ae1ff79c1
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00003.png differ
diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00004.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00004.png
new file mode 100644
index 000000000..034e96f49
Binary files /dev/null and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00004.png differ
diff --git a/tests/snapshots/nanox_eip191_opensea/00008.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00008.png
rename to tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png
diff --git a/tests/snapshots/nanox_eip191_nonascii/00004.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00006.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00004.png
rename to tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00006.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00007.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00009.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00007.png
rename to tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00009.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00000.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00000.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00000.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00000.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00001.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00001.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00001.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00001.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00002.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00002.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00002.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00002.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00003.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00003.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00003.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00003.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00004.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00004.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00004.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00004.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00005.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00005.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00005.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00005.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00006.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00006.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00007.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00007.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00007.png
rename to tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00007.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00000.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00000.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00000.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00000.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00001.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00001.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00001.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00001.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00002.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00002.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00002.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00002.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00003.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00003.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00003.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00003.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00004.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00004.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00004.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00004.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00005.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00005.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00005.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00005.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00006.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00006.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00006.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00006.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00007.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00007.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00007.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00007.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00008.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00008.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00009.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00009.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00009.png
rename to tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00009.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00000.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00000.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00000.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00000.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00001.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00001.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00001.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00001.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00002.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00002.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00002.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00002.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00003.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00003.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00003.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00003.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00004.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00004.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00004.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00004.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00005.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00005.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00005.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00005.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00006.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00006.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00007.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00007.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00007.png
rename to tests/speculos/screenshots/erc721/nanox/transfer_erc721/00007.png
diff --git a/tests/speculos/screenshots/pubkey/nanos/get_public_key/00000.png b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00000.png
new file mode 100644
index 000000000..63778c416
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00000.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/get_public_key/00001.png b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00001.png
new file mode 100644
index 000000000..63fe23c20
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00001.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/get_public_key/00002.png b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00002.png
new file mode 100644
index 000000000..b79ecb43c
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00002.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/get_public_key/00003.png b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00003.png
new file mode 100644
index 000000000..0b61bde37
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00003.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/get_public_key/00004.png b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00004.png
new file mode 100644
index 000000000..66c411c2e
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/get_public_key/00004.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00000.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00000.png
new file mode 100644
index 000000000..63778c416
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00000.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00001.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00001.png
new file mode 100644
index 000000000..63fe23c20
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00001.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00002.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00002.png
new file mode 100644
index 000000000..b79ecb43c
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00002.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00003.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00003.png
new file mode 100644
index 000000000..0b61bde37
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00003.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00004.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00004.png
new file mode 100644
index 000000000..66c411c2e
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00004.png differ
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00008.png b/tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00005.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00008.png
rename to tests/speculos/screenshots/pubkey/nanos/reject_get_public_key/00005.png
diff --git a/tests/speculos/screenshots/pubkey/nanox/get_public_key/00000.png b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00000.png
new file mode 100644
index 000000000..a487005a8
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00000.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanox/get_public_key/00001.png b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00001.png
new file mode 100644
index 000000000..5b381b6c9
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00001.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanox/get_public_key/00002.png b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00002.png
new file mode 100644
index 000000000..53ae65195
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/get_public_key/00002.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00000.png b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00000.png
new file mode 100644
index 000000000..a487005a8
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00000.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00001.png b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00001.png
new file mode 100644
index 000000000..5b381b6c9
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00001.png differ
diff --git a/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00002.png b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00002.png
new file mode 100644
index 000000000..53ae65195
Binary files /dev/null and b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00002.png differ
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00006.png b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00006.png
rename to tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00000.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00000.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00000.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00000.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00001.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00001.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00001.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00001.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00001.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00001.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00002.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00002.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00002.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00003.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00003.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00003.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00004.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00004.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00004.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00005.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00005.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00005.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00006.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00006.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00006.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00007.png
diff --git a/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00008.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00008.png
new file mode 100644
index 000000000..0aa6e196a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00008.png differ
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00008.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00008.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00009.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00007.png b/tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00010.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00007.png
rename to tests/speculos/screenshots/sign/nanos/blind_and_nonce_display/00010.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00000.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00000.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00000.png
diff --git a/tests/speculos/screenshots/sign/nanos/blind_simple/00001.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00001.png
new file mode 100644
index 000000000..b2ab3717e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/blind_simple/00001.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum/00001.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00001.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00002.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00002.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00002.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00003.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00003.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00003.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00004.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00004.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00004.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00005.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00005.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00005.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00006.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00006.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00006.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00007.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00008.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00008.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00008.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00009.png b/tests/speculos/screenshots/sign/nanos/blind_simple/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00009.png
rename to tests/speculos/screenshots/sign/nanos/blind_simple/00009.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00000.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00000.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00000.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00001.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00001.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00001.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00001.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00002.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00002.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00002.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00003.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00003.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00003.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00004.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00004.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00004.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00005.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00005.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00005.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00006.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00006.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00006.png
diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png
new file mode 100644
index 000000000..f0a7d0e1a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum/00007.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00007.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00008.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00009.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00009.png
rename to tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00009.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00000.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00000.png
rename to tests/speculos/screenshots/sign/nanos/limit_nonce/00000.png
diff --git a/tests/speculos/screenshots/sign/nanos/limit_nonce/00001.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/limit_nonce/00001.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/limit_nonce/00002.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00002.png
new file mode 100644
index 000000000..eaf18d9f7
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/limit_nonce/00002.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/limit_nonce/00003.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00003.png
new file mode 100644
index 000000000..87688c673
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/limit_nonce/00003.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00004.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00004.png
rename to tests/speculos/screenshots/sign/nanos/limit_nonce/00004.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00005.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00005.png
rename to tests/speculos/screenshots/sign/nanos/limit_nonce/00005.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00006.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00006.png
rename to tests/speculos/screenshots/sign/nanos/limit_nonce/00006.png
diff --git a/tests/speculos/screenshots/sign/nanos/limit_nonce/00007.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00007.png
new file mode 100644
index 000000000..933691b4e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/limit_nonce/00007.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum/00008.png b/tests/speculos/screenshots/sign/nanos/limit_nonce/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00008.png
rename to tests/speculos/screenshots/sign/nanos/limit_nonce/00008.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00000.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00000.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00000.png
diff --git a/tests/speculos/screenshots/sign/nanos/nonce_display/00001.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/nonce_display/00001.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00002.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00002.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00002.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00003.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00003.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00003.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00004.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00004.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00004.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00005.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00005.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00005.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00006.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00006.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00006.png
diff --git a/tests/speculos/screenshots/sign/nanos/nonce_display/00007.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00007.png
new file mode 100644
index 000000000..46e1645eb
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/nonce_display/00007.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/nonce_display/00008.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00008.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/nonce_display/00008.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00009.png b/tests/speculos/screenshots/sign/nanos/nonce_display/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00009.png
rename to tests/speculos/screenshots/sign/nanos/nonce_display/00009.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00000.png b/tests/speculos/screenshots/sign/nanos/reject/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00000.png
rename to tests/speculos/screenshots/sign/nanos/reject/00000.png
diff --git a/tests/speculos/screenshots/sign/nanos/reject/00001.png b/tests/speculos/screenshots/sign/nanos/reject/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/reject/00001.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00002.png b/tests/speculos/screenshots/sign/nanos/reject/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00002.png
rename to tests/speculos/screenshots/sign/nanos/reject/00002.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00003.png b/tests/speculos/screenshots/sign/nanos/reject/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00003.png
rename to tests/speculos/screenshots/sign/nanos/reject/00003.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00004.png b/tests/speculos/screenshots/sign/nanos/reject/00004.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00004.png
rename to tests/speculos/screenshots/sign/nanos/reject/00004.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00005.png b/tests/speculos/screenshots/sign/nanos/reject/00005.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00005.png
rename to tests/speculos/screenshots/sign/nanos/reject/00005.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00006.png b/tests/speculos/screenshots/sign/nanos/reject/00006.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00006.png
rename to tests/speculos/screenshots/sign/nanos/reject/00006.png
diff --git a/tests/speculos/screenshots/sign/nanos/reject/00007.png b/tests/speculos/screenshots/sign/nanos/reject/00007.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/reject/00007.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00008.png b/tests/speculos/screenshots/sign/nanos/reject/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00008.png
rename to tests/speculos/screenshots/sign/nanos/reject/00008.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00009.png b/tests/speculos/screenshots/sign/nanos/reject/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00009.png
rename to tests/speculos/screenshots/sign/nanos/reject/00009.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00000.png b/tests/speculos/screenshots/sign/nanos/simple/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00000.png
rename to tests/speculos/screenshots/sign/nanos/simple/00000.png
diff --git a/tests/speculos/screenshots/sign/nanos/simple/00001.png b/tests/speculos/screenshots/sign/nanos/simple/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/simple/00001.png differ
diff --git a/tests/snapshots/nanos_transfer_palm_network/00002.png b/tests/speculos/screenshots/sign/nanos/simple/00002.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00002.png
rename to tests/speculos/screenshots/sign/nanos/simple/00002.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00003.png b/tests/speculos/screenshots/sign/nanos/simple/00003.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00003.png
rename to tests/speculos/screenshots/sign/nanos/simple/00003.png
diff --git a/tests/speculos/screenshots/sign/nanos/simple/00004.png b/tests/speculos/screenshots/sign/nanos/simple/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/simple/00004.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/simple/00005.png b/tests/speculos/screenshots/sign/nanos/simple/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/simple/00005.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/simple/00006.png b/tests/speculos/screenshots/sign/nanos/simple/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/simple/00006.png differ
diff --git a/tests/speculos/screenshots/sign/nanos/simple/00007.png b/tests/speculos/screenshots/sign/nanos/simple/00007.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanos/simple/00007.png differ
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00013.png b/tests/speculos/screenshots/sign/nanos/simple/00008.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00013.png
rename to tests/speculos/screenshots/sign/nanos/simple/00008.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00000.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00000.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00000.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00000.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00001.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00001.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00001.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00001.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00002.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00002.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00002.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00003.png
diff --git a/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00004.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00004.png
new file mode 100644
index 000000000..61f368707
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00004.png differ
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00004.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00004.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00005.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00006.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00005.png
rename to tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00006.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00000.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00000.png
rename to tests/speculos/screenshots/sign/nanox/blind_simple/00000.png
diff --git a/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png
new file mode 100644
index 000000000..990173650
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum/00001.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00001.png
rename to tests/speculos/screenshots/sign/nanox/blind_simple/00002.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00002.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00002.png
rename to tests/speculos/screenshots/sign/nanox/blind_simple/00003.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00004.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00004.png
rename to tests/speculos/screenshots/sign/nanox/blind_simple/00004.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00005.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00005.png
rename to tests/speculos/screenshots/sign/nanox/blind_simple/00005.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00000.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00000.png
rename to tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00000.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00001.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00001.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00001.png
rename to tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00001.png
diff --git a/tests/snapshots/nanox_transfer_ethereum/00002.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00002.png
rename to tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00002.png
diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png
new file mode 100644
index 000000000..7037eb59e
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum/00003.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00003.png
rename to tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00004.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00005.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00005.png
rename to tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00005.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00000.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00000.png
rename to tests/speculos/screenshots/sign/nanox/limit_nonce/00000.png
diff --git a/tests/speculos/screenshots/sign/nanox/limit_nonce/00001.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00001.png
new file mode 100644
index 000000000..84aba2c71
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/limit_nonce/00001.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00002.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00002.png
rename to tests/speculos/screenshots/sign/nanox/limit_nonce/00002.png
diff --git a/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png
new file mode 100644
index 000000000..3edd720b3
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum/00004.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00004.png
rename to tests/speculos/screenshots/sign/nanox/limit_nonce/00004.png
diff --git a/tests/snapshots/nanox_transfer_ethereum/00000.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00000.png
rename to tests/speculos/screenshots/sign/nanox/nonce_display/00000.png
diff --git a/tests/speculos/screenshots/sign/nanox/nonce_display/00001.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/nonce_display/00001.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00002.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00002.png
rename to tests/speculos/screenshots/sign/nanox/nonce_display/00002.png
diff --git a/tests/speculos/screenshots/sign/nanox/nonce_display/00003.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00003.png
new file mode 100644
index 000000000..45b4d1304
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/nonce_display/00003.png differ
diff --git a/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00005.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00005.png
rename to tests/speculos/screenshots/sign/nanox/nonce_display/00005.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00000.png b/tests/speculos/screenshots/sign/nanox/reject/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00000.png
rename to tests/speculos/screenshots/sign/nanox/reject/00000.png
diff --git a/tests/speculos/screenshots/sign/nanox/reject/00001.png b/tests/speculos/screenshots/sign/nanox/reject/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/reject/00001.png differ
diff --git a/tests/snapshots/nanox_transfer_palm_network/00002.png b/tests/speculos/screenshots/sign/nanox/reject/00002.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00002.png
rename to tests/speculos/screenshots/sign/nanox/reject/00002.png
diff --git a/tests/speculos/screenshots/sign/nanox/reject/00003.png b/tests/speculos/screenshots/sign/nanox/reject/00003.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/reject/00003.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00004.png b/tests/speculos/screenshots/sign/nanox/reject/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00004.png
rename to tests/speculos/screenshots/sign/nanox/reject/00004.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00005.png b/tests/speculos/screenshots/sign/nanox/reject/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00005.png
rename to tests/speculos/screenshots/sign/nanox/reject/00005.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00000.png b/tests/speculos/screenshots/sign/nanox/simple/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00000.png
rename to tests/speculos/screenshots/sign/nanox/simple/00000.png
diff --git a/tests/speculos/screenshots/sign/nanox/simple/00001.png b/tests/speculos/screenshots/sign/nanox/simple/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/simple/00001.png differ
diff --git a/tests/speculos/screenshots/sign/nanox/simple/00002.png b/tests/speculos/screenshots/sign/nanox/simple/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/simple/00002.png differ
diff --git a/tests/speculos/screenshots/sign/nanox/simple/00003.png b/tests/speculos/screenshots/sign/nanox/simple/00003.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/speculos/screenshots/sign/nanox/simple/00003.png differ
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00009.png b/tests/speculos/screenshots/sign/nanox/simple/00004.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00009.png
rename to tests/speculos/screenshots/sign/nanox/simple/00004.png
diff --git a/tests/speculos/setup.cfg b/tests/speculos/setup.cfg
new file mode 100644
index 000000000..c79fd882c
--- /dev/null
+++ b/tests/speculos/setup.cfg
@@ -0,0 +1,20 @@
+[tool:pytest]
+addopts = --strict-markers
+
+[pylint]
+disable = C0114,  # missing-module-docstring
+          C0115,  # missing-class-docstring
+          C0116,  # missing-function-docstring
+          C0103,  # invalid-name
+          R0801,  # duplicate-code
+          R0913   # too-many-arguments
+extension-pkg-whitelist=hid
+
+[pycodestyle]
+max-line-length = 90
+
+[mypy-hid.*]
+ignore_missing_imports = True
+
+[mypy-pytest.*]
+ignore_missing_imports = True
diff --git a/tests/speculos/test_configuration_cmd.py b/tests/speculos/test_configuration_cmd.py
new file mode 100644
index 000000000..6f9e5e063
--- /dev/null
+++ b/tests/speculos/test_configuration_cmd.py
@@ -0,0 +1,10 @@
+
+def test_configuration(cmd):
+    if cmd.model == "nanos":
+        assert cmd.get_configuration() == (14, 1, 9, 20)
+    
+    if cmd.model == "nanox":
+        assert cmd.get_configuration() == (14, 1, 9, 20)
+
+    if cmd.model == "nanosp":
+        assert cmd.get_configuration() == (14, 1, 9, 20)
\ No newline at end of file
diff --git a/tests/speculos/test_eip1559.py b/tests/speculos/test_eip1559.py
new file mode 100644
index 000000000..f834df36c
--- /dev/null
+++ b/tests/speculos/test_eip1559.py
@@ -0,0 +1,64 @@
+from time import sleep
+
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG, parse_sign_response
+
+def test_sign_eip_1559(cmd):
+    result: list = []
+    # with bip32_path "44'/60'/0'/0/0"
+    apdu_sign_eip_1559 = bytes.fromhex("e004000088058000002c8000003c80000000000000000000000002f87001018502540be4008502540be40086246139ca800094cccccccccccccccccccccccccccccccccccccccc8000c001a0e07fb8a64ea3786c9a6649e54429e2786af3ea31c6d06165346678cf8ce44f9ba00e4a0526db1e905b7164a858fd5ebd2f1759e22e6955499448bd276a6aa62830")
+
+    with cmd.send_apdu_context(apdu_sign_eip_1559, result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00006.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00002.png")
+            cmd.client.press_and_release('right')
+            
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/eip1559/{PATH_IMG[cmd.model]}/sign_eip_1559/00004.png")
+            cmd.client.press_and_release('both')
+
+    response: bytes = result[0]
+    v, r, s = parse_sign_response(response)
+
+    assert v == 0x01
+    assert r.hex() == "3d6dfabc6c52374bfa34cb2c433856a0bcd9484870dd1b50249f7164a5fce052"
+    assert s.hex() == "0548a774dd0b63930d83cb2e1a836fe3ef24444e8b758b00585d9a076c0e98a8"
diff --git a/tests/speculos/test_eip2930.py b/tests/speculos/test_eip2930.py
new file mode 100644
index 000000000..972cbc576
--- /dev/null
+++ b/tests/speculos/test_eip2930.py
@@ -0,0 +1,72 @@
+from time import sleep
+
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG, parse_sign_response
+
+def test_sign_eip_2930(cmd):
+    result: list = []
+    apdu_sign_eip_2930 = bytes.fromhex("e004000096058000002c8000003c80000000000000000000000001f886030685012a05f20082520894b2bb2b958afa2e96dab3f3ce7162b87daea39017872386f26fc1000080f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000007")
+
+    with cmd.send_apdu_context(apdu_sign_eip_2930, result) as ex:
+        sleep(0.5)
+
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Network
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00007.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Network
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/eip2930/{PATH_IMG[cmd.model]}/sign_eip_2930/00005.png")
+            cmd.client.press_and_release('both')
+
+
+    response: bytes = result[0]
+    v, r, s = parse_sign_response(response)
+
+    assert v == 0x01
+    assert r.hex() == "a74d82400f49d1f9d85f734c22a1648d4ab74bb6367bef54c6abb0936be3d8b7"
+    assert s.hex() == "7a84a09673394c3c1bd76be05620ee17a2d0ff32837607625efa433cc017854e"
diff --git a/tests/speculos/test_eip712.py b/tests/speculos/test_eip712.py
new file mode 100644
index 000000000..6a72aa477
--- /dev/null
+++ b/tests/speculos/test_eip712.py
@@ -0,0 +1,179 @@
+from time import sleep
+
+import pytest
+
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG, parse_sign_response
+from ethereum_client.transaction import EIP712
+import ethereum_client
+
+def test_sign_eip_712_hashed_msg(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0'/0"
+    transaction = EIP712(
+        domain_hash="c24f499b8c957196651b13edd64aaccc3980009674b2aea0966c8a56ba81278e",
+        msg_hash="9d96be8a7cca396e711a3ba356bd9878df02a726d753ddb6cda3c507d888bc77"
+    )
+
+    with cmd.sign_eip712(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+
+        if cmd.model == "nanos":
+            # Sign typed message
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Domain hash 1/4, 2/4, 3/4, 4/4
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Message hash 1/4, 2/4, 3/4, 4/4
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00006.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00007.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00009.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Sign typed message
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Domain hash 1/2, 2/2
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Message hash 1/2, 2/2
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Sign message
+            compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg/00005.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x1B #27
+    assert r.hex() == "b1cf3dd6f2902ae9b181e158cc07f6ee6e6c456360b18842ece0b947dec89f07"
+    assert s.hex() == "5372a9b1a495b76ccd75347b6f591867859fb73aa05a546b79c81073ddff5e8a"
+
+def test_sign_eip_712_hashed_msg_reject(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0'/0"
+    transaction = EIP712(
+        domain_hash="c24f499b8c957196651b13edd64aaccc3980009674b2aea0966c8a56ba81278e",
+        msg_hash="9d96be8a7cca396e711a3ba356bd9878df02a726d753ddb6cda3c507d888bc77"
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+        with cmd.sign_eip712(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            sleep(0.5)
+
+            if cmd.model == "nanos":
+                # Sign typed message
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Domain hash 1/4, 2/4, 3/4, 4/4
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00001.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00002.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00003.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00004.png")
+                cmd.client.press_and_release('right')
+
+                # Message hash 1/4, 2/4, 3/4, 4/4
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00005.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00006.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00007.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00008.png")
+                cmd.client.press_and_release('right')
+
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00009.png")
+                cmd.client.press_and_release('right')
+
+                # Cancel signature
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00010.png")
+                cmd.client.press_and_release('both')
+
+            if cmd.model == "nanox" or cmd.model == "nanosp":
+                # Sign typed message
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Domain hash 1/2, 2/2
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00001.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00002.png")
+                cmd.client.press_and_release('right')
+
+                # Message hash 1/2, 2/2
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00003.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00004.png")
+                cmd.client.press_and_release('right')
+
+                # Sign message
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00005.png")
+                cmd.client.press_and_release('right')
+
+                # Cancel signature
+                compare_screenshot(cmd, f"screenshots/eip712/{PATH_IMG[cmd.model]}/sign_eip_712_hashed_msg_reject/00006.png")
+                cmd.client.press_and_release('both')
+        assert error.args[0] == '0x6985'
+
+def test_sign_eip_712_bad_domain(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0'/0"
+    transaction = EIP712(
+        domain_hash="deadbeef",
+        msg_hash="9d96be8a7cca396e711a3ba356bd9878df02a726d753ddb6cda3c507d888bc77"
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+        with cmd.sign_eip712(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            pass
+
+        assert error.args[0] == '0x6a80'
+
+def test_sign_eip_712_bad_msg(cmd):
+    result: list = []
+
+    bip32_path="44'/60'/0'/0'/0"
+    transaction = EIP712(
+        domain_hash="c24f499b8c957196651b13edd64aaccc3980009674b2aea0966c8a56ba81278e",
+        msg_hash="deadbeef"
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+        with cmd.sign_eip712(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            pass
+
+        assert error.args[0] == '0x6a80'
\ No newline at end of file
diff --git a/tests/speculos/test_erc1155.py b/tests/speculos/test_erc1155.py
new file mode 100644
index 000000000..b0692ecd6
--- /dev/null
+++ b/tests/speculos/test_erc1155.py
@@ -0,0 +1,208 @@
+from time import sleep
+
+import pytest
+
+import ethereum_client
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG, parse_sign_response
+from ethereum_client.plugin import Plugin
+
+SIGN_FIRST = bytes.fromhex("e004000096058000002c8000003c800000000000000000000000f901090b8520b673dd0082bcb394495f947276749ce646f68ac8c248420045cb7b5e80b8e4f242432a0000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596cabf06640f8ca8fc5e0ed471b10befcdf65a33e4300000000")
+SIGN_MORE = bytes.fromhex("e00480008b00006a0000000064000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000043078303000000000000000000000000000000000000000000000000000000000018080")
+
+PLUGIN = Plugin(
+    type=1,
+    version=1,
+    name="ERC1155",
+    addr="0x495f947276749ce646f68ac8c248420045cb7b5e",
+    selector=0xf242432a,
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="3045022100ec4377d17e8d98d424bf16b29c691bc1a010825fb5b8a35de0268a9dc22eab2402206701b016fe6718bf519d18cc12e9838e9ef898cc4c143017839023c3260b2d74",
+)
+
+PROVIDE_NFT_INFORMATION = Plugin(
+    type=1,
+    version=1,
+    name="OpenSea Collection",
+    addr="0x495f947276749ce646f68ac8c248420045cb7b5e",
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="304502210083e357a828f13d574b1296214a3749c194ab1df1f8a243655c053b1c72f91e0c02201ed93cfac7e87759445c4da2e4bfd6e1cf0405ea37c7293bc965948f51bef5cc",
+)
+
+def test_transfer_erc1155(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        cmd.set_plugin(plugin=PLUGIN)
+        cmd.provide_nft_information(plugin=PROVIDE_NFT_INFORMATION)
+            
+        cmd.send_apdu(SIGN_FIRST)
+
+        with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+            sleep(0.5)
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00000.png")
+            cmd.client.press_and_release('right')
+            
+            # NFT Transfert
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00001.png")
+            cmd.client.press_and_release('right')
+
+            # To
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Collection Name
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00003.png")
+            cmd.client.press_and_release('right')
+
+            # NFT Address
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00004.png")
+            cmd.client.press_and_release('right')
+
+            # NFT ID 1/2, 2/2
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Quantity
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/transfer_erc1155/00009.png")
+            cmd.client.press_and_release('both')
+
+
+        response: bytes = result[0]
+        v, r, s = parse_sign_response(response)
+
+        assert v == 0x25 # 37
+        assert r.hex() == "ab3eca1a0b5c66bfe603252037682a024a12f92d799b4d74993a8bf4221bbe7d"
+        assert s.hex() == "24de0c0598d1d8e5ea99b75fa26105478f45f43b510e504fc1b14f07fe7dda2a"
+
+
+def test_transfer_erc1155_without_nft_provide_info(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+            cmd.set_plugin(plugin=PLUGIN)
+
+        
+            cmd.send_apdu(SIGN_FIRST)
+
+            with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+                pass
+
+            assert error.args[0] == '0x6a80'
+
+
+def test_transfer_erc1155_without_set_plugin(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+
+            cmd.provide_nft_information(plugin=PROVIDE_NFT_INFORMATION)
+            
+            cmd.send_apdu(SIGN_FIRST)
+
+            with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+                pass
+
+            assert error.args[0] == '0x6985'
+
+
+# ===========================
+#        Batch
+# ===========================
+
+SIGN_FIRST_BATCH  = bytes.fromhex("e004000096058000002c8000003c800000000000000000000000f9020b0e850d8cfd86008301617d94495f947276749ce646f68ac8c248420045cb7b5e80b901e42eb2c2d60000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596c00000000000000000000000000000000000000000000")
+SIGN_MORE_1_BATCH = bytes.fromhex("e004800096000000000000000000a0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000003abf06640f8ca8fc5e0ed471b10befcdf65a33e430000000000006a0000000064def9d99ff495856496c028c0")
+SIGN_MORE_2_BATCH = bytes.fromhex("e00480009689732473fcd0bbbe000000000000a30000000001abf06640f8ca8fc5e0ed471b10befcdf65a33e430000000000006a00000000640000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000010000")
+SIGN_MORE_3_BATCH = bytes.fromhex("e00480006100000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000043078303000000000000000000000000000000000000000000000000000000000018080")
+
+PLUGIN_BATCH = Plugin(
+    type=1,
+    version=1,
+    name="ERC1155",
+    addr="0x495f947276749ce646f68ac8c248420045cb7b5e",
+    selector=0x2eb2c2d6,
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="304502210087b35cefc53fd94e25404933eb0d5ff08f20ba655d181de3b24ff0099dc3317f02204a216aa9e0b84bef6e20fcb036bd49647bf0cab66732b99b49ec277ffb682aa1",
+)
+
+PROVIDE_NFT_INFORMATION_BATCH = Plugin(
+    type=1,
+    version=1,
+    name="OpenSea Shared Storefront",
+    addr="0x495f947276749ce646f68ac8c248420045cb7b5e",
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="3045022100c74cd613a27a9f4887210f5a3a0e12745e1ba0ab3a0d284cb6485d89c3cce4e602205a13e62a91164985cf58a838f8f531c0b91b980d206a5ba8df28270023ef93a3",
+)
+
+def test_transfer_batch_erc1155(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        cmd.set_plugin(plugin=PLUGIN_BATCH)
+        cmd.provide_nft_information(plugin=PROVIDE_NFT_INFORMATION_BATCH)
+            
+        cmd.send_apdu(SIGN_FIRST_BATCH)
+        cmd.send_apdu(SIGN_MORE_1_BATCH)
+        cmd.send_apdu(SIGN_MORE_2_BATCH)
+
+        with cmd.send_apdu_context(SIGN_MORE_3_BATCH, result) as ex:
+            sleep(0.5)
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00000.png")
+            cmd.client.press_and_release('right')
+
+            # NFT Batch Transfer
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00001.png")
+            cmd.client.press_and_release('right')
+
+            # To
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Collection Name
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00003.png")
+            cmd.client.press_and_release('right')
+
+            # NFT Address
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Total Quantity
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/erc1155/{PATH_IMG[cmd.model]}/test_transfer_batch_erc1155/00007.png")
+            cmd.client.press_and_release('both')
+
+        response: bytes = result[0]
+        v, r, s = parse_sign_response(response)
+
+        assert v == 0x25 # 37
+        assert r.hex() == "ee17b599747775a5056c6f654b476bdec0f3fea2c03a4754a31f736e61015082"
+        assert s.hex() == "3d76f264da438a5bda69389e59c08216e98ddb6649323bd5055980ae31f79c1c"
diff --git a/tests/speculos/test_erc20information.py b/tests/speculos/test_erc20information.py
new file mode 100644
index 000000000..9af2c7b3d
--- /dev/null
+++ b/tests/speculos/test_erc20information.py
@@ -0,0 +1,31 @@
+import pytest
+from ethereum_client.plugin import ERC20Information
+import ethereum_client
+
+def test_provide_erc20_token(cmd):
+    erc20_info = ERC20Information(
+        erc20_ticker="5a5258",
+        addr="0xe41d2489571d322189246dafa5ebde1f4699f498",
+        nb_decimals=18,
+        chainID=1,
+        sign="304402200ae8634c22762a8ba41d2acb1e068dcce947337c6dd984f13b820d396176952302203306a49d8a6c35b11a61088e1570b3928ca3a0db6bd36f577b5ef87628561ff7"
+    )
+
+    # Test if return 9000
+    try:
+        cmd.provide_erc20_token_information(info=erc20_info)
+    except:
+        raise
+
+def test_provide_erc20_token_error(cmd):
+    erc20_info = ERC20Information(
+        erc20_ticker="5a5258",
+        addr="0xe41d2489571d322189246dafa5ebde1f4699f498",
+        nb_decimals=18,
+        chainID=1,
+        sign="deadbeef"
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+        cmd.provide_erc20_token_information(info=erc20_info)
+        assert error.args[0] == '0x6a80'
\ No newline at end of file
diff --git a/tests/speculos/test_erc721.py b/tests/speculos/test_erc721.py
new file mode 100644
index 000000000..865250144
--- /dev/null
+++ b/tests/speculos/test_erc721.py
@@ -0,0 +1,115 @@
+from time import sleep
+
+import pytest
+
+import ethereum_client
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG, parse_sign_response
+from ethereum_client.plugin import Plugin
+
+SIGN_FIRST = bytes.fromhex("e004000096058000002c8000003c800000000000000000000000f88a0a852c3ce1ec008301f5679460f80121c31a0d46b5279700f9df786054aa5ee580b86442842e0e0000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596c000000000000000000000000000000000000000000000000")
+SIGN_MORE = bytes.fromhex("e00480000b0000000000112999018080")
+
+PLUGIN = Plugin(
+    type=1,
+    version=1,
+    name="ERC721",
+    addr="0x60f80121c31a0d46b5279700f9df786054aa5ee5",
+    selector=0x42842e0e,
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="304502202e2282d7d3ea714da283010f517af469e1d59654aaee0fc438f017aa557eaea50221008b369679381065bbe01135723a4f9adb229295017d37c4d30138b90a51cf6ab6",
+)
+
+PROVIDE_NFT_INFORMATION = Plugin(
+    type=1,
+    version=1,
+    name="Rarible",
+    addr="0x60f80121c31a0d46b5279700f9df786054aa5ee5",
+    chainID=1,
+    keyID=0,
+    algorithm=1,
+    sign="3045022025696986ef5f0ee2f72d9c6e41d7e2bf2e4f06373ab26d73ebe326c7fd4c7a6602210084f6b064d8750ae68ed5dd012296f37030390ec06ff534c5da6f0f4a4460af33",
+)
+
+def test_transfer_erc721(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        cmd.set_plugin(plugin=PLUGIN)
+        cmd.provide_nft_information(plugin=PROVIDE_NFT_INFORMATION)
+            
+        cmd.send_apdu(SIGN_FIRST)
+
+        with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+            sleep(0.5)
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00000.png")
+            cmd.client.press_and_release('right')
+                
+            # NFT Transfer
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00001.png")
+            cmd.client.press_and_release('right')
+
+            # To
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Collection Name
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00003.png")
+            cmd.client.press_and_release('right')
+
+            # NFT Address
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00004.png")
+            cmd.client.press_and_release('right')
+
+            # NFT ID
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/erc721/{PATH_IMG[cmd.model]}/transfer_erc721/00007.png")
+            cmd.client.press_and_release('both')
+
+        response: bytes = result[0]
+        v, r, s = parse_sign_response(response)
+
+        assert v == 0x25 # 37
+        assert r.hex() == "68ba082523584adbfc31d36d68b51d6f209ce0838215026bf1802a8f17dcdff4"
+        assert s.hex() == "7c92908fa05c8bc86507a3d6a1c8b3c2722ee01c836d89a61df60c1ab0b43fff"
+
+
+def test_transfer_erc721_without_nft_provide_info(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+            cmd.set_plugin(plugin=PLUGIN)
+
+            cmd.send_apdu(SIGN_FIRST)
+
+            with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+                pass
+
+            assert error.args[0] == '0x6a80'
+    
+
+
+def test_transfer_erc721_without_set_plugin(cmd):
+    result: list = []
+
+    if cmd.model == "nanox" or cmd.model == "nanosp":
+        with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+            cmd.provide_nft_information(plugin=PROVIDE_NFT_INFORMATION)
+            
+            cmd.send_apdu(SIGN_FIRST)
+
+            with cmd.send_apdu_context(SIGN_MORE, result) as ex:
+                pass
+        
+            assert error.args[0] == '0x6985'
\ No newline at end of file
diff --git a/tests/speculos/test_pubkey_cmd.py b/tests/speculos/test_pubkey_cmd.py
new file mode 100644
index 000000000..17f1d78b4
--- /dev/null
+++ b/tests/speculos/test_pubkey_cmd.py
@@ -0,0 +1,117 @@
+from time import sleep
+
+import pytest
+
+import ethereum_client
+from ethereum_client.utils import compare_screenshot, save_screenshot, PATH_IMG
+
+
+def test_get_public_key(cmd):
+    # ETHER COIN without display
+    result: list = []
+    with cmd.get_public_key(bip32_path="44'/60'/1'/0/0", display=False, result=result) as exchange:
+        pass
+
+    uncompressed_addr_len, eth_addr, chain_code = result
+
+    assert len(uncompressed_addr_len) == 65
+    assert len(eth_addr) == 40
+    assert len(chain_code) == 32
+
+    assert uncompressed_addr_len == b'\x04\xea\x02&\x91\xc7\x87\x00\xd2\xc3\xa0\xc7E\xbe\xa4\xf2\xb8\xe5\xe3\x13\x97j\x10B\xf6\xa1Vc\\\xb2\x05\xda\x1a\xcb\xfe\x04*\nZ\x89eyn6"E\x89\x0eT\xbd-\xbex\xec\x1e\x18df\xf2\xe9\xd0\xf5\xd5\xd8\xdf'
+    assert eth_addr == b'463e4e114AA57F54f2Fd2C3ec03572C6f75d84C2'
+    assert chain_code == b'\xaf\x89\xcd)\xea${8I\xec\xc80\xc2\xc8\x94\\e1\xd6P\x87\x07?\x9f\xd09\x00\xa0\xea\xa7\x96\xc8'
+
+    # DAI COIN with display
+    result: list = []
+    with cmd.get_public_key(bip32_path="44'/700'/1'/0/0", display=True, result=result) as exchange:
+        sleep(0.5)
+
+        if cmd.model == "nanos":
+            # Verify address
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Approved
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00004.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Verify address
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Approve
+            compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/get_public_key/00002.png")
+            cmd.client.press_and_release('both')
+
+    uncompressed_addr_len, eth_addr, chain_code = result
+    assert len(uncompressed_addr_len) == 65
+    assert len(eth_addr) == 40
+    assert len(chain_code) == 32
+
+    assert uncompressed_addr_len == b'\x04V\x8a\x15\xdc\xed\xc8[\x16\x17\x8d\xaf\xcax\x91v~{\x9c\x06\xba\xaa\xde\xf4\xe7\x9f\x86\x1d~\xed)\xdc\n8\x9c\x84\xf01@E\x13]\xd7~6\x8e\x8e\xabb-\xad\xcdo\xc3Fw\xb7\xc8y\xdbQ/\xc3\xe5\x18'
+    assert eth_addr == b'Ba9A9aED0a1AbBE1da1155F64e73e57Af7995880'
+    assert chain_code == b'4\xaa\x95\xf4\x02\x12\x12-T\x155\x86\xed\xc5\x0b\x1d8\x81\xae\xce\xbd\x1a\xbbv\x9a\xc7\xd5\x1a\xd0KT\xe4'
+
+
+def test_reject_get_public_key(cmd):
+    # DAI COIN with display
+    result: list = []
+
+    with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+
+        with cmd.get_public_key(bip32_path="44'/700'/1'/0/0", display=True, result=result) as exchange:
+            sleep(0.5)
+
+            if cmd.model == "nanos":
+                # Verify address
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Address 1/3, 2/3, 3/3
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00001.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00002.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00003.png")
+                cmd.client.press_and_release('right')
+
+                # Approve
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00004.png")
+                cmd.client.press_and_release('right')
+                
+                # Reject
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00005.png")
+                cmd.client.press_and_release('both')
+            
+            if cmd.model == "nanox" or cmd.model == "nanosp":
+                # Verify address
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Address
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00001.png")
+                cmd.client.press_and_release('right')
+
+                # Approve
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00002.png")
+                cmd.client.press_and_release('right')
+
+                # Reject
+                compare_screenshot(cmd, f"screenshots/pubkey/{PATH_IMG[cmd.model]}/reject_get_public_key/00003.png")
+                cmd.client.press_and_release('both')
+
+        assert error.args[0] == '0x6985'
diff --git a/tests/speculos/test_sign_cmd.py b/tests/speculos/test_sign_cmd.py
new file mode 100644
index 000000000..0e0207a33
--- /dev/null
+++ b/tests/speculos/test_sign_cmd.py
@@ -0,0 +1,704 @@
+from time import sleep
+
+import pytest
+
+import ethereum_client
+from ethereum_client.utils import compare_screenshot, compare_screenshot, save_screenshot, PATH_IMG
+from ethereum_client.transaction import Transaction
+
+
+# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
+
+def test_sign_simple(cmd):
+    result: list = []
+
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=68,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00008.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/simple/00004.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x26 # 38
+    assert r.hex() == "6f389d15320f0501383526ed03de917c14212716f09a262dbc98431086a5db49"
+    assert s.hex() == "0dc994b7b97230bb35fdf6fec2f4d8ff4cfb8bfeb2a652c364c738ff033c05dd"
+    
+
+def test_sign_dai_coin_type_on_network_5234(cmd):
+    result: list = []
+    
+    # DAI coin type
+    bip32_path="44'/700'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=0,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=5243,
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Network 5243
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00009.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Network 5243
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00005.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+    
+    assert v == 0x1A # 26
+    assert r.hex() == "7ebfa5d5cac1e16bb1f1a8c67706b5c6019c0f198df6bb44e742a9de72330961"
+    assert s.hex() == "537419d8d1443d38ea87943c110789decb43b8f4fea8fae256fe842f669da634"
+
+
+def test_sign_reject(cmd):
+    result: list = []
+    
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=0,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.DenyError) as error:
+
+        with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            sleep(0.5)
+
+            if cmd.model == "nanos":
+                # Review transaction
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Amount 1/3, 2/3, 3/3
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00001.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00002.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00003.png")
+                cmd.client.press_and_release('right')
+
+                # Address 1/3, 2/3, 3/3
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00004.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00005.png")
+                cmd.client.press_and_release('right')
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00006.png")
+                cmd.client.press_and_release('right')
+
+                # Max Fees
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00007.png")
+                cmd.client.press_and_release('right')
+
+                # Accept and send
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00008.png")
+                cmd.client.press_and_release('right')
+                
+                # Reject
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00009.png")
+                cmd.client.press_and_release('both')
+
+            if cmd.model == "nanox" or cmd.model == "nanosp":
+                # Review transaction
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00000.png")
+                cmd.client.press_and_release('right')
+
+                # Amount
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00001.png")
+                cmd.client.press_and_release('right')
+
+                # Address
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00002.png")
+                cmd.client.press_and_release('right')
+
+                # Max Fees
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00003.png")
+                cmd.client.press_and_release('right')
+
+                # Accept and send
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00004.png")
+                cmd.client.press_and_release('right')
+
+                # Reject
+                compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/reject/00005.png")
+                cmd.client.press_and_release('both')
+
+        assert error.args[0] == '0x6985'
+
+
+def test_sign_limit_nonce(cmd):
+    result: list = []
+    
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    # EIP-2681: Limit account nonce to 2^64-1
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=2**64-1,
+        gasPrice=10,
+        gasLimit=50000,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x08762,
+        chainID=1,
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00008.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/limit_nonce/00004.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x26 # 38
+    assert r.hex() == "7f17f9efa5a6065f885a44a5f5d68a62381c6b2b23047817b4569c61ccf571c6"
+    assert s.hex() == "4b67d37cfe473e0b2daf246fa82c7595bcff0c1515d69089037d0c061f14b3b3"
+
+
+def test_sign_error_transaction_type(cmd):
+    result: list = []
+    
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    # the txType is between 0x00 and 0x7F
+    transaction = Transaction(
+        txType=0x00,
+        nonce=0,
+        gasPrice=10,
+        gasLimit=50000,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x19,
+        chainID=1,
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+        with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            pass
+
+        assert error.args[0] == '0x6501'
+
+    transaction.txType = 0x7F
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+        with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            pass
+
+        assert error.args[0] == '0x6501'
+
+
+def test_sign_nonce_display(cmd):
+    # Activate nonce display
+    # Application is ready
+    cmd.client.press_and_release('left')
+    # Quit
+    cmd.client.press_and_release('left')
+    # Settings
+    cmd.client.press_and_release('both')
+    # Blind signing
+    cmd.client.press_and_release('right')
+    # Debug data
+    cmd.client.press_and_release('right')
+    # Nonce display
+    cmd.client.press_and_release('both')
+    cmd.client.press_and_release('right')
+    # Back
+    cmd.client.press_and_release('both')
+
+    result: list = []
+
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=68,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00001.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00004.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00006.png")
+            cmd.client.press_and_release('right')
+
+            # Nonce
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00009.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Nonce
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/nonce_display/00005.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x26 # 38
+    assert r.hex() == "6f389d15320f0501383526ed03de917c14212716f09a262dbc98431086a5db49"
+    assert s.hex() == "0dc994b7b97230bb35fdf6fec2f4d8ff4cfb8bfeb2a652c364c738ff033c05dd"
+
+
+def test_sign_blind_simple(cmd):
+    # Activate blind signing
+    # Application is ready
+    cmd.client.press_and_release('left')
+    # Quit
+    cmd.client.press_and_release('left')
+    # Settings
+    cmd.client.press_and_release('both')
+    # Blind signing
+    cmd.client.press_and_release('both')
+    cmd.client.press_and_release('right')
+    # Debug data
+    cmd.client.press_and_release('right')
+    # Nonce display
+    cmd.client.press_and_release('right')
+    # Back
+    cmd.client.press_and_release('both')
+
+    result: list = []
+
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=68,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+        data="ok",
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Blind Signing
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00006.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00009.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Blind Signing
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_simple/00005.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x26 # 38
+    assert r.hex() == "98163696ad14f54e0e7207306b6f66665131cee601052facab8fd24250e15470"
+    assert s.hex() == "318e573fc809f7dcb8f9718c8bd2946b2c3c83cedf3720e66e06fb63ceea3174"
+
+
+def test_sign_blind_error_disabled(cmd):
+    result: list = []
+
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=68,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+        data="ok",
+    )
+
+    with pytest.raises(ethereum_client.exception.errors.UnknownDeviceError) as error:
+
+        with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+            sleep(0.5)
+
+            if cmd.model == "nanos":
+                pass
+            if cmd.model == "nanox" or cmd.model == "nanosp":
+                pass
+
+        assert error.args[0] == '0x6a80'
+
+
+def test_sign_blind_and_nonce_display(cmd):
+    # Activate blind signing
+    # Application is ready
+    cmd.client.press_and_release('left')
+    # Quit
+    cmd.client.press_and_release('left')
+    # Settings
+    cmd.client.press_and_release('both')
+    # Blind signing
+    cmd.client.press_and_release('both')
+    cmd.client.press_and_release('right')
+    # Debug data
+    cmd.client.press_and_release('right')
+    # Nonce display
+    cmd.client.press_and_release('both')
+    cmd.client.press_and_release('right')
+    # Back
+    cmd.client.press_and_release('both')
+
+    result: list = []
+
+    # Ether coin type
+    bip32_path="44'/60'/1'/0/0"
+
+    transaction = Transaction(
+        txType=0xEB,
+        nonce=2**64-1,
+        gasPrice=0x0306dc4200,
+        gasLimit=0x5208,
+        to="0x5a321744667052affa8386ed49e00ef223cbffc3",
+        value=0x6f9c9e7bf61818,
+        chainID=1,
+        data="That's a little message :)",
+    )
+
+    with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex:
+        sleep(0.5)
+        
+        if cmd.model == "nanos":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Blind Signing
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Amount 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00002.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00003.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Address 1/3, 2/3, 3/3
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00005.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00006.png")
+            cmd.client.press_and_release('right')
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00007.png")
+            cmd.client.press_and_release('right')
+
+            # Nonce
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00008.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00009.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00010.png")
+            cmd.client.press_and_release('both')
+
+        if cmd.model == "nanox" or cmd.model == "nanosp":
+            # Review transaction
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00000.png")
+            cmd.client.press_and_release('right')
+
+            # Blind Signing
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00001.png")
+            cmd.client.press_and_release('right')
+
+            # Amount
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00002.png")
+            cmd.client.press_and_release('right')
+
+            # Address
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00003.png")
+            cmd.client.press_and_release('right')
+
+            # Nonce
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00004.png")
+            cmd.client.press_and_release('right')
+
+            # Max Fees
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00005.png")
+            cmd.client.press_and_release('right')
+
+            # Accept and send
+            compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/blind_and_nonce_display/00006.png")
+            cmd.client.press_and_release('both')
+
+    v, r, s = result
+
+    assert v == 0x25 # 37
+    assert r.hex() == "737c07042022d37286216312d62163c4238536d82c5b45937ce9fbf259d11b7d"
+    assert s.hex() == "5604485e0cf37e465a84290eb26a18e40a430f1b0fda184c56b2c3a51ada2e6c"
diff --git a/tests/unit/.gitignore b/tests/unit/.gitignore
new file mode 100644
index 000000000..2cbee4ed1
--- /dev/null
+++ b/tests/unit/.gitignore
@@ -0,0 +1,22 @@
+# Editor Files and Folders
+
+.idea/
+.vscode/
+.DS_Store
+*~
+\#*#
+
+# Build Files and Binaries
+
+*.log
+*.o
+*.so
+*.dll
+*.dylib
+cmake-build-*/
+*build/
+build/
+
+# Coverage file
+coverage.info
+coverage
\ No newline at end of file
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
new file mode 100644
index 000000000..93605b2df
--- /dev/null
+++ b/tests/unit/CMakeLists.txt
@@ -0,0 +1,65 @@
+cmake_minimum_required(VERSION 3.10)
+
+if(${CMAKE_VERSION} VERSION_LESS 3.10)
+    cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
+endif()
+
+# project information
+project(unit_tests
+        VERSION 0.1
+	      DESCRIPTION "Unit tests for C project"
+        LANGUAGES C)
+
+
+# guard against bad build-type strings
+if (NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE "Debug")
+endif()
+
+include(CTest)
+ENABLE_TESTING()
+
+# specify C standard
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_C_STANDARD_REQUIRED True)
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -pedantic -g -O0 --coverage")
+
+set(GCC_COVERAGE_LINK_FLAGS "--coverage -lgcov")
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
+
+# guard against in-source builds
+if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
+  message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
+endif()
+
+# Fetch cmocka
+find_package(cmocka QUIET)
+include(FetchContent)
+FetchContent_Declare(
+    cmocka
+    GIT_REPOSITORY https://git.cryptomilk.org/projects/cmocka.git
+    GIT_TAG        cmocka-1.1.5
+    GIT_SHALLOW    1
+)
+set(WITH_STATIC_LIB ON CACHE BOOL "CMocka: Build with a static library" FORCE)
+set(WITH_CMOCKERY_SUPPORT OFF CACHE BOOL "CMocka: Install a cmockery header" FORCE)
+set(WITH_EXAMPLES OFF CACHE BOOL "CMocka: Build examples" FORCE)
+set(UNIT_TESTING OFF CACHE BOOL "CMocka: Build with unit testing" FORCE)
+set(PICKY_DEVELOPER OFF CACHE BOOL "CMocka: Build with picky developer flags" FORCE)
+FetchContent_MakeAvailable(cmocka)
+
+add_compile_definitions(TEST DEBUG=0 SKIP_FOR_CMOCKA)
+
+include_directories(../../src/)
+include_directories(../../src_common)
+
+# add cmocka tests
+add_executable(test_demo tests/demo.c)
+
+# add src
+add_library(demo SHARED ./demo_tu.c)
+
+target_link_libraries(test_demo PUBLIC cmocka gcov demo)
+
+add_test(test_demo test_demo)
\ No newline at end of file
diff --git a/tests/unit/Makefile b/tests/unit/Makefile
new file mode 100644
index 000000000..71d8a14fc
--- /dev/null
+++ b/tests/unit/Makefile
@@ -0,0 +1,42 @@
+MAKEFLAGS	+=	--no-print-directory
+
+RM			?=	rm -f
+ECHO		=	`which echo`
+
+ifneq (,$(findstring xterm,${TERM}))
+GREEN       := $(shell tput -Txterm setaf 2)
+RED         := $(shell tput -Txterm setaf 1)
+CYAN         := $(shell tput -Txterm setaf 6)
+RESET 		:= $(shell tput -Txterm sgr0)
+else
+GREEN       := ""
+RED         := ""
+RESET       := ""
+endif
+
+BUILD_DIRECTORY	=	$(realpath build/)
+
+DIRECTORY_BUILD = build
+
+all:
+	@cmake -B ${DIRECTORY_BUILD} -H.
+	@make -C ${DIRECTORY_BUILD}
+	@CTEST_OUTPUT_ON_FAILURE=1 make -C ${DIRECTORY_BUILD} test
+
+coverage: all
+	@lcov --directory . -b "${BUILD_DIRECTORY}" --capture --initial -o coverage.base
+	@lcov --rc lcov_branch_coverage=1 --directory . -b "${BUILD_DIRECTORY}" --capture -o coverage.capture
+	@lcov --directory . -b "${BUILD_DIRECTORY}" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info
+	@lcov --directory . -b "${BUILD_DIRECTORY}" --remove coverage.info '*/unit-tests/*' -o coverage.info --remove coverage.info '*/build/_deps/cmocka-src/src/*'
+	@$(ECHO) -e "${GREEN}[ OK ]${RESET} Generated 'coverage.info'."
+	@genhtml coverage.info -o coverage
+	@if [ -f coverage.base ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.base && $(RM) -r coverage.base ; fi;
+	@if [ -f coverage.capture ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.capture && $(RM) -r coverage.capture ; fi;
+	@$(ECHO) -e "${CYAN}[ REDIRECT ]${RESET}" `realpath coverage/index.html` && xdg-open `realpath coverage/index.html`
+
+clean:
+	@if [ -d ${DIRECTORY_BUILD} ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" ${DIRECTORY_BUILD} && $(RM) -r ${DIRECTORY_BUILD} ; fi;
+	@if [ -d coverage ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage && $(RM) -r coverage ; fi;
+	@if [ -f coverage.info ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.info && $(RM) -r coverage.info ; fi;
+
+.PHONY: all coverage clean
\ No newline at end of file
diff --git a/tests/unit/README.md b/tests/unit/README.md
new file mode 100644
index 000000000..68a98f28b
--- /dev/null
+++ b/tests/unit/README.md
@@ -0,0 +1,38 @@
+# Unit tests
+
+It is important to unit test your functions.  
+This also allows you to document how your functions work.  
+We use the library [**cmocka**](https://cmocka.org/#features)
+
+## Requirement
+
+- [CMake >= 3.10](https://cmake.org/download/)
+- [lcov >= 1.14](http://ltp.sourceforge.net/coverage/lcov.php)
+
+Don't worry, you don't necessarily need to install the `cmocka library` because the **cmakelist automatically fetches** the library
+
+## Add new test
+
+Create new file into `tests` folder and follow [this initiation](https://cmocka.org/talks/cmocka_unit_testing_and_mocking.pdf)  
+
+Now go to the `CMakeLists.txt` file and add your test with the specific file you want to test.
+
+## Usage
+
+### Build
+
+The `default rules` of makefile will compile the tests and run them.
+
+```sh
+make
+```
+
+The `coverage rule` will launch the default rules and generate the coverage and you will be **automatically redirected** to the generated .html
+```sh
+make coverage
+```
+
+The `clean rule` will delete the folders and files generated
+```sh
+make clean
+```
\ No newline at end of file
diff --git a/tests/unit/demo_tu.c b/tests/unit/demo_tu.c
new file mode 100644
index 000000000..c4f450cad
--- /dev/null
+++ b/tests/unit/demo_tu.c
@@ -0,0 +1,12 @@
+#include <string.h>
+
+int local_strchr_demo(char *string, char ch) {
+    unsigned int length = strlen(string);
+    unsigned int i;
+    for (i = 0; i < length; i++) {
+        if (string[i] == ch) {
+            return i;
+        }
+    }
+    return -1;
+}
\ No newline at end of file
diff --git a/tests/unit/tests/demo.c b/tests/unit/tests/demo.c
new file mode 100644
index 000000000..1da227dc9
--- /dev/null
+++ b/tests/unit/tests/demo.c
@@ -0,0 +1,18 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+int local_strchr_demo(char *string, char ch);
+
+static void null_test_success(void **state) {
+    assert_int_equal(local_strchr_demo("salut", 'c'), -1);
+    assert_int_equal(local_strchr_demo("av", 'a'), 0);
+}
+
+int main(void) {
+    const struct CMUnitTest tests[] = {
+        cmocka_unit_test(null_test_success),
+    };
+    return cmocka_run_group_tests(tests, NULL, NULL);
+}
\ No newline at end of file
diff --git a/tests/.babelrc b/tests/zemu/.babelrc
similarity index 100%
rename from tests/.babelrc
rename to tests/zemu/.babelrc
diff --git a/tests/.flowconfig b/tests/zemu/.flowconfig
similarity index 100%
rename from tests/.flowconfig
rename to tests/zemu/.flowconfig
diff --git a/tests/zemu/.gitignore b/tests/zemu/.gitignore
new file mode 100644
index 000000000..826d3f011
--- /dev/null
+++ b/tests/zemu/.gitignore
@@ -0,0 +1,4 @@
+/node_modules
+/snapshots-tmp
+/elfs
+/lib
\ No newline at end of file
diff --git a/tests/zemu/Makefile b/tests/zemu/Makefile
new file mode 100644
index 000000000..82d770661
--- /dev/null
+++ b/tests/zemu/Makefile
@@ -0,0 +1,8 @@
+MAKEFLAGS	+=	--no-print-directory
+
+all:
+	./build_local_test_elfs.sh
+	yarn install
+	yarn test
+
+.PHONY: all
\ No newline at end of file
diff --git a/tests/build_local_test_elfs.sh b/tests/zemu/build_local_test_elfs.sh
similarity index 100%
rename from tests/build_local_test_elfs.sh
rename to tests/zemu/build_local_test_elfs.sh
diff --git a/tests/globalsetup.js b/tests/zemu/globalsetup.js
similarity index 100%
rename from tests/globalsetup.js
rename to tests/zemu/globalsetup.js
diff --git a/tests/jest.config.js b/tests/zemu/jest.config.js
similarity index 100%
rename from tests/jest.config.js
rename to tests/zemu/jest.config.js
diff --git a/tests/zemu/jest.js b/tests/zemu/jest.js
new file mode 100644
index 000000000..521ecbe62
--- /dev/null
+++ b/tests/zemu/jest.js
@@ -0,0 +1,22 @@
+export default jest;
+export const { expect, test } = global;
+
+export const sim_options_s = {
+  model: "nanos",
+  logging: true,
+  start_delay: 2000,
+  X11: true,
+  custom: "",
+};
+
+export const sim_options_x = {
+  model: "nanox",
+  logging: true,
+  start_delay: 2000,
+  X11: true,
+  custom: "",
+};
+
+export const Resolve = require("path").resolve;
+export const NANOS_ELF_PATH = Resolve("elfs/ethereum_nanos.elf");
+export const NANOX_ELF_PATH = Resolve("elfs/ethereum_nanox.elf");
\ No newline at end of file
diff --git a/tests/package.json b/tests/zemu/package.json
similarity index 100%
rename from tests/package.json
rename to tests/zemu/package.json
diff --git a/tests/setupTests.js b/tests/zemu/setupTests.js
similarity index 100%
rename from tests/setupTests.js
rename to tests/zemu/setupTests.js
diff --git a/tests/snapshots/nanos_transfer_palm_network/00000.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00000.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00000.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00000.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00001.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00001.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00001.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00001.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00002.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00002.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00002.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00002.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00003.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00003.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00003.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00003.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00004.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00004.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00004.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00004.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00005.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00005.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00005.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00005.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00006.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00006.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00006.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00006.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00009.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00009.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00007.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00008.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00008.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00008.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00008.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00009.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00009.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00009.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00009.png
diff --git a/tests/snapshots/nanos_approve_dai_tokens/00010.png b/tests/zemu/snapshots/nanos_approve_dai_tokens/00010.png
similarity index 100%
rename from tests/snapshots/nanos_approve_dai_tokens/00010.png
rename to tests/zemu/snapshots/nanos_approve_dai_tokens/00010.png
diff --git a/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00000.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00001.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00001.png
new file mode 100644
index 000000000..b2ab3717e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00001.png differ
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00002.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00002.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00002.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00002.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00003.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00003.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00003.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00003.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00004.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00004.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00004.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00004.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00005.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00005.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00005.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00005.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00006.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00006.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00006.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00006.png
diff --git a/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00007.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00007.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00007.png differ
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00014.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00008.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00014.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00008.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00009.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00009.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00009.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00009.png
diff --git a/tests/snapshots/nanos_deposit_eth_compound_blind/00010.png b/tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00010.png
similarity index 100%
rename from tests/snapshots/nanos_deposit_eth_compound_blind/00010.png
rename to tests/zemu/snapshots/nanos_deposit_eth_compound_blind/00010.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00000.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00000.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00000.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00000.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00001.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00001.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00001.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00001.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00002.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00002.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00002.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00002.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00003.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00003.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00003.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00003.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00004.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00004.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00004.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00004.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00005.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00005.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00005.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00005.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00006.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00006.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00006.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00006.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00007.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00007.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00007.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00007.png
diff --git a/tests/snapshots/nanos_disable_blind_signing/00008.png b/tests/zemu/snapshots/nanos_disable_blind_signing/00008.png
similarity index 100%
rename from tests/snapshots/nanos_disable_blind_signing/00008.png
rename to tests/zemu/snapshots/nanos_disable_blind_signing/00008.png
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00000.png b/tests/zemu/snapshots/nanos_eip191_metamask/00000.png
new file mode 100644
index 000000000..ab16f62bf
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00001.png b/tests/zemu/snapshots/nanos_eip191_metamask/00001.png
new file mode 100644
index 000000000..b90315cd3
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00002.png b/tests/zemu/snapshots/nanos_eip191_metamask/00002.png
new file mode 100644
index 000000000..3d90dfd93
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00003.png b/tests/zemu/snapshots/nanos_eip191_metamask/00003.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00004.png b/tests/zemu/snapshots/nanos_eip191_metamask/00004.png
new file mode 100644
index 000000000..d55782f42
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_metamask/00005.png b/tests/zemu/snapshots/nanos_eip191_metamask/00005.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_metamask/00005.png differ
diff --git a/tests/snapshots/nanos_eip191_metamask/00006.png b/tests/zemu/snapshots/nanos_eip191_metamask/00006.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_metamask/00006.png
rename to tests/zemu/snapshots/nanos_eip191_metamask/00006.png
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00000.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00000.png
new file mode 100644
index 000000000..ab16f62bf
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00001.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00001.png
new file mode 100644
index 000000000..51efae064
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00002.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00002.png
new file mode 100644
index 000000000..b4e4df511
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00003.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00003.png
new file mode 100644
index 000000000..d95e83116
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00004.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00004.png
new file mode 100644
index 000000000..e8c4c8e78
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00005.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00005.png
new file mode 100644
index 000000000..a259c69de
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00006.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00006.png
new file mode 100644
index 000000000..4ce22f64e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00006.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00007.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00007.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00007.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00008.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00008.png
new file mode 100644
index 000000000..d55782f42
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00008.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_nonascii/00009.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00009.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_nonascii/00009.png differ
diff --git a/tests/snapshots/nanos_eip191_nonascii/00008.png b/tests/zemu/snapshots/nanos_eip191_nonascii/00010.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_nonascii/00008.png
rename to tests/zemu/snapshots/nanos_eip191_nonascii/00010.png
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00000.png b/tests/zemu/snapshots/nanos_eip191_opensea/00000.png
new file mode 100644
index 000000000..ab16f62bf
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00001.png b/tests/zemu/snapshots/nanos_eip191_opensea/00001.png
new file mode 100644
index 000000000..bdbb3a0f2
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00002.png b/tests/zemu/snapshots/nanos_eip191_opensea/00002.png
new file mode 100644
index 000000000..1fd81705b
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00003.png b/tests/zemu/snapshots/nanos_eip191_opensea/00003.png
new file mode 100644
index 000000000..582648da5
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00004.png b/tests/zemu/snapshots/nanos_eip191_opensea/00004.png
new file mode 100644
index 000000000..53e131782
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00005.png b/tests/zemu/snapshots/nanos_eip191_opensea/00005.png
new file mode 100644
index 000000000..b1bddfeb4
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00006.png b/tests/zemu/snapshots/nanos_eip191_opensea/00006.png
new file mode 100644
index 000000000..f872acc96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00006.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00007.png b/tests/zemu/snapshots/nanos_eip191_opensea/00007.png
new file mode 100644
index 000000000..56b7f7b3b
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00007.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00008.png b/tests/zemu/snapshots/nanos_eip191_opensea/00008.png
new file mode 100644
index 000000000..d5c4fde63
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00008.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00009.png b/tests/zemu/snapshots/nanos_eip191_opensea/00009.png
new file mode 100644
index 000000000..407da907e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00009.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00010.png b/tests/zemu/snapshots/nanos_eip191_opensea/00010.png
new file mode 100644
index 000000000..481c8dccd
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00010.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00011.png b/tests/zemu/snapshots/nanos_eip191_opensea/00011.png
new file mode 100644
index 000000000..ff9dba946
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00011.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00012.png b/tests/zemu/snapshots/nanos_eip191_opensea/00012.png
new file mode 100644
index 000000000..e179c2993
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00012.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00013.png b/tests/zemu/snapshots/nanos_eip191_opensea/00013.png
new file mode 100644
index 000000000..f872acc96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00013.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00014.png b/tests/zemu/snapshots/nanos_eip191_opensea/00014.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00014.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00015.png b/tests/zemu/snapshots/nanos_eip191_opensea/00015.png
new file mode 100644
index 000000000..d55782f42
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00015.png differ
diff --git a/tests/zemu/snapshots/nanos_eip191_opensea/00016.png b/tests/zemu/snapshots/nanos_eip191_opensea/00016.png
new file mode 100644
index 000000000..f5c2d6774
Binary files /dev/null and b/tests/zemu/snapshots/nanos_eip191_opensea/00016.png differ
diff --git a/tests/snapshots/nanos_eip191_opensea/00009.png b/tests/zemu/snapshots/nanos_eip191_opensea/00017.png
similarity index 100%
rename from tests/snapshots/nanos_eip191_opensea/00009.png
rename to tests/zemu/snapshots/nanos_eip191_opensea/00017.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00000.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00000.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00000.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00000.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00001.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00001.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00001.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00001.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00002.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00002.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00002.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00002.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00003.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00003.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00003.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00003.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00004.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00004.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00004.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00004.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00005.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00005.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00005.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00005.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00006.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00006.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00006.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00006.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00007.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00007.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00007.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00007.png
diff --git a/tests/snapshots/nanos_enable_blind_signing/00008.png b/tests/zemu/snapshots/nanos_enable_blind_signing/00008.png
similarity index 100%
rename from tests/snapshots/nanos_enable_blind_signing/00008.png
rename to tests/zemu/snapshots/nanos_enable_blind_signing/00008.png
diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png differ
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00001.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00001.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00001.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00001.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00002.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00002.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00002.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00002.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00003.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00003.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00003.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00003.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00004.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00004.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00004.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00004.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00005.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00005.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00005.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00005.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00006.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00006.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00006.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00006.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00007.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00007.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00007.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00007.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00008.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00008.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00008.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00008.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00009.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00009.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00009.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00009.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00010.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00010.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00010.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00010.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00011.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00011.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00011.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00011.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00012.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00012.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00012.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00012.png
diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png differ
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00010.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00014.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00010.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00014.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00015.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00015.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00015.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00015.png
diff --git a/tests/snapshots/nanos_starkware_usdt_deposit/00016.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00016.png
similarity index 100%
rename from tests/snapshots/nanos_starkware_usdt_deposit/00016.png
rename to tests/zemu/snapshots/nanos_starkware_usdt_deposit/00016.png
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00000.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00002.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00003.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00004.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00005.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00006.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00007.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00007.png
rename to tests/zemu/snapshots/nanos_transfer_112233445566_network/00007.png
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00009.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00009.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00009.png differ
diff --git a/tests/snapshots/nanos_transfer_bsc/00010.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00010.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00010.png
rename to tests/zemu/snapshots/nanos_transfer_112233445566_network/00010.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00011.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00011.png
rename to tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png
diff --git a/tests/snapshots/nanos_transfer_112233445566_network/00012.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00012.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_112233445566_network/00012.png
rename to tests/zemu/snapshots/nanos_transfer_112233445566_network/00012.png
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00000.png b/tests/zemu/snapshots/nanos_transfer_bsc/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00000.png differ
diff --git a/tests/snapshots/nanos_transfer_bsc/00001.png b/tests/zemu/snapshots/nanos_transfer_bsc/00001.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00001.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00001.png
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00002.png b/tests/zemu/snapshots/nanos_transfer_bsc/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00003.png b/tests/zemu/snapshots/nanos_transfer_bsc/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00004.png b/tests/zemu/snapshots/nanos_transfer_bsc/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00005.png b/tests/zemu/snapshots/nanos_transfer_bsc/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00006.png b/tests/zemu/snapshots/nanos_transfer_bsc/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_bsc/00007.png b/tests/zemu/snapshots/nanos_transfer_bsc/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00007.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00007.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00008.png b/tests/zemu/snapshots/nanos_transfer_bsc/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00008.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00008.png
diff --git a/tests/zemu/snapshots/nanos_transfer_bsc/00009.png b/tests/zemu/snapshots/nanos_transfer_bsc/00009.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_bsc/00009.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00010.png b/tests/zemu/snapshots/nanos_transfer_bsc/00010.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00010.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00010.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00011.png b/tests/zemu/snapshots/nanos_transfer_bsc/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00011.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00011.png
diff --git a/tests/snapshots/nanos_transfer_bsc/00012.png b/tests/zemu/snapshots/nanos_transfer_bsc/00012.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_bsc/00012.png
rename to tests/zemu/snapshots/nanos_transfer_bsc/00012.png
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00000.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00001.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00001.png
new file mode 100644
index 000000000..9f2651390
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00002.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00002.png
new file mode 100644
index 000000000..701b26bfc
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00003.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00003.png
new file mode 100644
index 000000000..32a2ee929
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00004.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00004.png
new file mode 100644
index 000000000..1ed3d773d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00005.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00005.png
new file mode 100644
index 000000000..f19d91cc0
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_eip1559/00006.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00006.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_eip1559/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_eip1559/00007.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00007.png
rename to tests/zemu/snapshots/nanos_transfer_eip1559/00007.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00008.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00008.png
rename to tests/zemu/snapshots/nanos_transfer_eip1559/00008.png
diff --git a/tests/snapshots/nanos_transfer_eip1559/00009.png b/tests/zemu/snapshots/nanos_transfer_eip1559/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_eip1559/00009.png
rename to tests/zemu/snapshots/nanos_transfer_eip1559/00009.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00000.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00001.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00002.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00003.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00004.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00005.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00006.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00006.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00007.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00007.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00007.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum/00008.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00008.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum/00008.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00009.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00009.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00009.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum/00009.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00010.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00010.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00010.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum/00010.png
diff --git a/tests/snapshots/nanos_transfer_ethereum/00011.png b/tests/zemu/snapshots/nanos_transfer_ethereum/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum/00011.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum/00011.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png
new file mode 100644
index 000000000..7ebda4f3a
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00007.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00007.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00007.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png
new file mode 100644
index 000000000..c84d3ec3e
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png differ
diff --git a/tests/snapshots/nanos_transfer_palm_network/00010.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00010.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00010.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00010.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00011.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00011.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00011.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_5234_network/00012.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00012.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_5234_network/00012.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00012.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00000.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00000.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00001.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00001.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00001.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_clone/00001.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00002.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00003.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00004.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00005.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00006.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00007.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00007.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_clone/00007.png
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00008.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00008.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00008.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00009.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00009.png
new file mode 100644
index 000000000..9c7e7049c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00009.png differ
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00010.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00010.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00010.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_clone/00010.png
diff --git a/tests/snapshots/nanos_transfer_ethereum_clone/00011.png b/tests/zemu/snapshots/nanos_transfer_ethereum_clone/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_ethereum_clone/00011.png
rename to tests/zemu/snapshots/nanos_transfer_ethereum_clone/00011.png
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00000.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00000.png
new file mode 100644
index 000000000..8d84cc70f
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00000.png differ
diff --git a/tests/snapshots/nanos_transfer_palm_network/00001.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00001.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00001.png
rename to tests/zemu/snapshots/nanos_transfer_palm_network/00001.png
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00002.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00002.png
new file mode 100644
index 000000000..c2af54e96
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00002.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00003.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00003.png
new file mode 100644
index 000000000..a54fefd4c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00003.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00004.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00004.png
new file mode 100644
index 000000000..8656b8175
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00004.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00005.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00005.png
new file mode 100644
index 000000000..fd3155c0d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00005.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00006.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00006.png
new file mode 100644
index 000000000..c63f25f8d
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00006.png differ
diff --git a/tests/snapshots/nanos_transfer_palm_network/00007.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00007.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00007.png
rename to tests/zemu/snapshots/nanos_transfer_palm_network/00007.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00008.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00008.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00008.png
rename to tests/zemu/snapshots/nanos_transfer_palm_network/00008.png
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00009.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00009.png
new file mode 100644
index 000000000..1c9156c31
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00009.png differ
diff --git a/tests/zemu/snapshots/nanos_transfer_palm_network/00010.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00010.png
new file mode 100644
index 000000000..9c7e7049c
Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_palm_network/00010.png differ
diff --git a/tests/snapshots/nanos_transfer_palm_network/00011.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00011.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00011.png
rename to tests/zemu/snapshots/nanos_transfer_palm_network/00011.png
diff --git a/tests/snapshots/nanos_transfer_palm_network/00012.png b/tests/zemu/snapshots/nanos_transfer_palm_network/00012.png
similarity index 100%
rename from tests/snapshots/nanos_transfer_palm_network/00012.png
rename to tests/zemu/snapshots/nanos_transfer_palm_network/00012.png
diff --git a/tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00000.png b/tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00000.png
similarity index 100%
rename from tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00000.png
rename to tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00000.png
diff --git a/tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00001.png b/tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00001.png
similarity index 100%
rename from tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00001.png
rename to tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00001.png
diff --git a/tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00002.png b/tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00002.png
similarity index 100%
rename from tests/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00002.png
rename to tests/zemu/snapshots/nanos_try_to_blind_sign_with_setting_disabled/00002.png
diff --git a/tests/snapshots/nanox_transfer_palm_network/00000.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00000.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00000.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00000.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00001.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00001.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00001.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00001.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00002.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00002.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00002.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00002.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00003.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00003.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00003.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00003.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00004.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00004.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00004.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00004.png
diff --git a/tests/snapshots/nanox_transfer_palm_network/00005.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00005.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00005.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00006.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00006.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00006.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00006.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00007.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00007.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00007.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00007.png
diff --git a/tests/snapshots/nanox_approve_dai_tokens/00008.png b/tests/zemu/snapshots/nanox_approve_dai_tokens/00008.png
similarity index 100%
rename from tests/snapshots/nanox_approve_dai_tokens/00008.png
rename to tests/zemu/snapshots/nanox_approve_dai_tokens/00008.png
diff --git a/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00000.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00001.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00001.png
new file mode 100644
index 000000000..990173650
Binary files /dev/null and b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00001.png differ
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00002.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00002.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00002.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00002.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00003.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00003.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00003.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00003.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00004.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00004.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00004.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00004.png
diff --git a/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00005.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00005.png differ
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00006.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00006.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00006.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00007.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00007.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00007.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00007.png
diff --git a/tests/snapshots/nanox_deposit_eth_compound_blind/00008.png b/tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00008.png
similarity index 100%
rename from tests/snapshots/nanox_deposit_eth_compound_blind/00008.png
rename to tests/zemu/snapshots/nanox_deposit_eth_compound_blind/00008.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00000.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00000.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00000.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00000.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00001.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00001.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00001.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00001.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00002.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00002.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00002.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00002.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00003.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00003.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00003.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00003.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00004.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00004.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00004.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00004.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00005.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00005.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00005.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00005.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00006.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00006.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00006.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00006.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00007.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00007.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00007.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00007.png
diff --git a/tests/snapshots/nanox_disable_blind_signing/00008.png b/tests/zemu/snapshots/nanox_disable_blind_signing/00008.png
similarity index 100%
rename from tests/snapshots/nanox_disable_blind_signing/00008.png
rename to tests/zemu/snapshots/nanox_disable_blind_signing/00008.png
diff --git a/tests/zemu/snapshots/nanox_eip191_metamask/00000.png b/tests/zemu/snapshots/nanox_eip191_metamask/00000.png
new file mode 100644
index 000000000..1b271542d
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_metamask/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_metamask/00001.png b/tests/zemu/snapshots/nanox_eip191_metamask/00001.png
new file mode 100644
index 000000000..58f060626
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_metamask/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_metamask/00002.png b/tests/zemu/snapshots/nanox_eip191_metamask/00002.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_metamask/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_metamask/00003.png b/tests/zemu/snapshots/nanox_eip191_metamask/00003.png
new file mode 100644
index 000000000..121cfd59e
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_metamask/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_metamask/00004.png b/tests/zemu/snapshots/nanox_eip191_metamask/00004.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_metamask/00004.png differ
diff --git a/tests/snapshots/nanox_eip191_metamask/00005.png b/tests/zemu/snapshots/nanox_eip191_metamask/00005.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_metamask/00005.png
rename to tests/zemu/snapshots/nanox_eip191_metamask/00005.png
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00000.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00000.png
new file mode 100644
index 000000000..1b271542d
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00001.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00001.png
new file mode 100644
index 000000000..6a5f8e8c3
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00002.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00002.png
new file mode 100644
index 000000000..78d7d1df5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00003.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00003.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00004.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00004.png
new file mode 100644
index 000000000..121cfd59e
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_nonascii/00005.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00005.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_nonascii/00005.png differ
diff --git a/tests/snapshots/nanox_eip191_nonascii/00006.png b/tests/zemu/snapshots/nanox_eip191_nonascii/00006.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_nonascii/00006.png
rename to tests/zemu/snapshots/nanox_eip191_nonascii/00006.png
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00000.png b/tests/zemu/snapshots/nanox_eip191_opensea/00000.png
new file mode 100644
index 000000000..1b271542d
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00001.png b/tests/zemu/snapshots/nanox_eip191_opensea/00001.png
new file mode 100644
index 000000000..4f59a8d40
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00002.png b/tests/zemu/snapshots/nanox_eip191_opensea/00002.png
new file mode 100644
index 000000000..c094bc635
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00003.png b/tests/zemu/snapshots/nanox_eip191_opensea/00003.png
new file mode 100644
index 000000000..9a3efb771
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00004.png b/tests/zemu/snapshots/nanox_eip191_opensea/00004.png
new file mode 100644
index 000000000..657edb555
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00005.png b/tests/zemu/snapshots/nanox_eip191_opensea/00005.png
new file mode 100644
index 000000000..1f135ae15
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00005.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00006.png b/tests/zemu/snapshots/nanox_eip191_opensea/00006.png
new file mode 100644
index 000000000..952e5ca8a
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00006.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00007.png b/tests/zemu/snapshots/nanox_eip191_opensea/00007.png
new file mode 100644
index 000000000..f29ed004a
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00007.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00008.png b/tests/zemu/snapshots/nanox_eip191_opensea/00008.png
new file mode 100644
index 000000000..8af3d9cae
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00008.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00009.png b/tests/zemu/snapshots/nanox_eip191_opensea/00009.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00009.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00010.png b/tests/zemu/snapshots/nanox_eip191_opensea/00010.png
new file mode 100644
index 000000000..121cfd59e
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00010.png differ
diff --git a/tests/zemu/snapshots/nanox_eip191_opensea/00011.png b/tests/zemu/snapshots/nanox_eip191_opensea/00011.png
new file mode 100644
index 000000000..c9da92b60
Binary files /dev/null and b/tests/zemu/snapshots/nanox_eip191_opensea/00011.png differ
diff --git a/tests/snapshots/nanox_erc1155_transfer/00012.png b/tests/zemu/snapshots/nanox_eip191_opensea/00012.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00012.png
rename to tests/zemu/snapshots/nanox_eip191_opensea/00012.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00000.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00000.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00000.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00000.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00001.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00001.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00001.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00001.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00002.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00002.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00002.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00002.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00003.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00003.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00003.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00003.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00004.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00004.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00004.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00004.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00005.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00005.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00005.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00005.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00006.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00006.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00006.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00006.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00007.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00007.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00007.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00007.png
diff --git a/tests/snapshots/nanox_enable_blind_signing/00008.png b/tests/zemu/snapshots/nanox_enable_blind_signing/00008.png
similarity index 100%
rename from tests/snapshots/nanox_enable_blind_signing/00008.png
rename to tests/zemu/snapshots/nanox_enable_blind_signing/00008.png
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00000.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00001.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00001.png
new file mode 100644
index 000000000..ba1dfa0e3
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00002.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00002.png
new file mode 100644
index 000000000..7d01fe80c
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00003.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00003.png
new file mode 100644
index 000000000..950fd72aa
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00004.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00004.png
new file mode 100644
index 000000000..5906d1967
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00005.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00005.png
new file mode 100644
index 000000000..05c1afa85
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00005.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00006.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00006.png
new file mode 100644
index 000000000..690bb3d26
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00006.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00007.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00007.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00007.png differ
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00008.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00008.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00008.png
rename to tests/zemu/snapshots/nanox_erc1155_batch_transfer/00008.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00009.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00009.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00009.png
rename to tests/zemu/snapshots/nanox_erc1155_batch_transfer/00009.png
diff --git a/tests/snapshots/nanox_erc1155_batch_transfer/00010.png b/tests/zemu/snapshots/nanox_erc1155_batch_transfer/00010.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_batch_transfer/00010.png
rename to tests/zemu/snapshots/nanox_erc1155_batch_transfer/00010.png
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00000.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00001.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00001.png
new file mode 100644
index 000000000..2b0fd141f
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00002.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00002.png
new file mode 100644
index 000000000..7d01fe80c
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00003.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00003.png
new file mode 100644
index 000000000..a5790c197
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00004.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00004.png
new file mode 100644
index 000000000..5906d1967
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00005.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00005.png
new file mode 100644
index 000000000..d6257d347
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00005.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00006.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00006.png
new file mode 100644
index 000000000..061c754c7
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00006.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00007.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00007.png
new file mode 100644
index 000000000..c748a750b
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00007.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00008.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00008.png
new file mode 100644
index 000000000..cd509d990
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00008.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer/00009.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00009.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer/00009.png differ
diff --git a/tests/snapshots/nanox_erc1155_transfer/00010.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00010.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00010.png
rename to tests/zemu/snapshots/nanox_erc1155_transfer/00010.png
diff --git a/tests/snapshots/nanox_erc1155_transfer/00011.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00011.png
similarity index 100%
rename from tests/snapshots/nanox_erc1155_transfer/00011.png
rename to tests/zemu/snapshots/nanox_erc1155_transfer/00011.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00012.png b/tests/zemu/snapshots/nanox_erc1155_transfer/00012.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00012.png
rename to tests/zemu/snapshots/nanox_erc1155_transfer/00012.png
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00000.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00000.png
new file mode 120000
index 000000000..a808e251a
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00000.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00000.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00001.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00001.png
new file mode 120000
index 000000000..18b62b5da
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00001.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00001.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00002.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00002.png
new file mode 120000
index 000000000..3ba3b504f
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00002.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00002.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00003.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00003.png
new file mode 100644
index 000000000..b34af53fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00004.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00004.png
new file mode 120000
index 000000000..d5f595812
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00004.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00004.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00005.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00005.png
new file mode 120000
index 000000000..0d2033d8b
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00005.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00005.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00006.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00006.png
new file mode 120000
index 000000000..ce6215953
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00006.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00006.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00007.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00007.png
new file mode 120000
index 000000000..e9c683ad5
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00007.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00007.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00008.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00008.png
new file mode 120000
index 000000000..8dc90445d
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00008.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00008.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00009.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00009.png
new file mode 120000
index 000000000..8293fcb24
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00009.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00009.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00010.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00010.png
new file mode 120000
index 000000000..76c0110fe
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00010.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00010.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00011.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00011.png
new file mode 120000
index 000000000..e2f437469
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00011.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00011.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00012.png b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00012.png
new file mode 120000
index 000000000..24a2c61de
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc1155_transfer_wo_info/00012.png
@@ -0,0 +1,1 @@
+../nanox_erc1155_transfer/00012.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00000.png b/tests/zemu/snapshots/nanox_erc721_transfer/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00001.png b/tests/zemu/snapshots/nanox_erc721_transfer/00001.png
new file mode 100644
index 000000000..2b0fd141f
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00002.png b/tests/zemu/snapshots/nanox_erc721_transfer/00002.png
new file mode 100644
index 000000000..7d01fe80c
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00003.png b/tests/zemu/snapshots/nanox_erc721_transfer/00003.png
new file mode 100644
index 000000000..9e8c446eb
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00004.png b/tests/zemu/snapshots/nanox_erc721_transfer/00004.png
new file mode 100644
index 000000000..23f2a4504
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00005.png b/tests/zemu/snapshots/nanox_erc721_transfer/00005.png
new file mode 100644
index 000000000..e369a1bb9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00005.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00006.png b/tests/zemu/snapshots/nanox_erc721_transfer/00006.png
new file mode 100644
index 000000000..6ce12bac1
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00006.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer/00007.png b/tests/zemu/snapshots/nanox_erc721_transfer/00007.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer/00007.png differ
diff --git a/tests/snapshots/nanox_erc721_transfer/00008.png b/tests/zemu/snapshots/nanox_erc721_transfer/00008.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00008.png
rename to tests/zemu/snapshots/nanox_erc721_transfer/00008.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00009.png b/tests/zemu/snapshots/nanox_erc721_transfer/00009.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00009.png
rename to tests/zemu/snapshots/nanox_erc721_transfer/00009.png
diff --git a/tests/snapshots/nanox_erc721_transfer/00010.png b/tests/zemu/snapshots/nanox_erc721_transfer/00010.png
similarity index 100%
rename from tests/snapshots/nanox_erc721_transfer/00010.png
rename to tests/zemu/snapshots/nanox_erc721_transfer/00010.png
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00000.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00000.png
new file mode 120000
index 000000000..eaca370e9
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00000.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00000.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00001.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00001.png
new file mode 120000
index 000000000..3f0242006
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00001.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00001.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00002.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00002.png
new file mode 120000
index 000000000..55b219fcc
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00002.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00002.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00003.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00003.png
new file mode 100644
index 000000000..b34af53fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00004.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00004.png
new file mode 120000
index 000000000..4e66c9ac3
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00004.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00004.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00005.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00005.png
new file mode 120000
index 000000000..b538cb6a2
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00005.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00005.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00006.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00006.png
new file mode 120000
index 000000000..9d4b34350
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00006.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00006.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00007.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00007.png
new file mode 120000
index 000000000..8851ec8fb
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00007.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00007.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00008.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00008.png
new file mode 120000
index 000000000..7faf831db
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00008.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00008.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00009.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00009.png
new file mode 120000
index 000000000..d3f938b04
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00009.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00009.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00010.png b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00010.png
new file mode 120000
index 000000000..8e813645c
--- /dev/null
+++ b/tests/zemu/snapshots/nanox_erc721_transfer_wo_info/00010.png
@@ -0,0 +1,1 @@
+../nanox_erc721_transfer/00010.png
\ No newline at end of file
diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00000.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00000.png differ
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00001.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00001.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00001.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00001.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00002.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00002.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00002.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00002.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00003.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00003.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00003.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00003.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00004.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00004.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00004.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00004.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00005.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00005.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00005.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00005.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00006.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00006.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00006.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00006.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00007.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00007.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00007.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00007.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00008.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00008.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00008.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00008.png
diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00009.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00009.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00009.png differ
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00010.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00010.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00010.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00010.png
diff --git a/tests/snapshots/nanox_starkware_usdt_deposit/00011.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00011.png
similarity index 100%
rename from tests/snapshots/nanox_starkware_usdt_deposit/00011.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00011.png
diff --git a/tests/snapshots/nanox_eip191_opensea/00009.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00012.png
similarity index 100%
rename from tests/snapshots/nanox_eip191_opensea/00009.png
rename to tests/zemu/snapshots/nanox_starkware_usdt_deposit/00012.png
diff --git a/tests/zemu/snapshots/nanox_transfer_112233445566_network/00000.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_112233445566_network/00001.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_112233445566_network/00002.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00002.png differ
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00003.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00003.png
rename to tests/zemu/snapshots/nanox_transfer_112233445566_network/00003.png
diff --git a/tests/zemu/snapshots/nanox_transfer_112233445566_network/00004.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_112233445566_network/00005.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00005.png differ
diff --git a/tests/snapshots/nanox_transfer_bsc/00006.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00006.png
rename to tests/zemu/snapshots/nanox_transfer_112233445566_network/00006.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00007.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00007.png
rename to tests/zemu/snapshots/nanox_transfer_112233445566_network/00007.png
diff --git a/tests/snapshots/nanox_transfer_112233445566_network/00008.png b/tests/zemu/snapshots/nanox_transfer_112233445566_network/00008.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_112233445566_network/00008.png
rename to tests/zemu/snapshots/nanox_transfer_112233445566_network/00008.png
diff --git a/tests/zemu/snapshots/nanox_transfer_bsc/00000.png b/tests/zemu/snapshots/nanox_transfer_bsc/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_bsc/00000.png differ
diff --git a/tests/snapshots/nanox_transfer_bsc/00001.png b/tests/zemu/snapshots/nanox_transfer_bsc/00001.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00001.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00001.png
diff --git a/tests/zemu/snapshots/nanox_transfer_bsc/00002.png b/tests/zemu/snapshots/nanox_transfer_bsc/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_bsc/00002.png differ
diff --git a/tests/snapshots/nanox_transfer_bsc/00003.png b/tests/zemu/snapshots/nanox_transfer_bsc/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00003.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00003.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00004.png b/tests/zemu/snapshots/nanox_transfer_bsc/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00004.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00004.png
diff --git a/tests/zemu/snapshots/nanox_transfer_bsc/00005.png b/tests/zemu/snapshots/nanox_transfer_bsc/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_bsc/00005.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00006.png b/tests/zemu/snapshots/nanox_transfer_bsc/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00006.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00006.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00007.png b/tests/zemu/snapshots/nanox_transfer_bsc/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00007.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00007.png
diff --git a/tests/snapshots/nanox_transfer_bsc/00008.png b/tests/zemu/snapshots/nanox_transfer_bsc/00008.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_bsc/00008.png
rename to tests/zemu/snapshots/nanox_transfer_bsc/00008.png
diff --git a/tests/zemu/snapshots/nanox_transfer_eip1559/00000.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_eip1559/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_eip1559/00001.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00001.png
new file mode 100644
index 000000000..cdcc19d05
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_eip1559/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_eip1559/00002.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00002.png
new file mode 100644
index 000000000..5b65b54dc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_eip1559/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_eip1559/00003.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00003.png
new file mode 100644
index 000000000..1a7a3f353
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_eip1559/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_eip1559/00004.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00004.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_eip1559/00004.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum/00005.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00005.png
rename to tests/zemu/snapshots/nanox_transfer_eip1559/00005.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00006.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00006.png
rename to tests/zemu/snapshots/nanox_transfer_eip1559/00006.png
diff --git a/tests/snapshots/nanox_transfer_eip1559/00007.png b/tests/zemu/snapshots/nanox_transfer_eip1559/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_eip1559/00007.png
rename to tests/zemu/snapshots/nanox_transfer_eip1559/00007.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum/00000.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum/00001.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum/00002.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum/00002.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum/00003.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00003.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum/00003.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum/00004.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00004.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum/00004.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00005.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00005.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00005.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum/00005.png
diff --git a/tests/snapshots/nanox_transfer_ethereum/00006.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00006.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum/00006.png
diff --git a/tests/snapshots/nanox_transfer_ethereum/00007.png b/tests/zemu/snapshots/nanox_transfer_ethereum/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum/00007.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum/00007.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00000.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00000.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png
new file mode 100644
index 000000000..0976a317a
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00003.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00003.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00003.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00005.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00005.png differ
diff --git a/tests/snapshots/nanox_transfer_palm_network/00006.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00006.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00006.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00007.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00007.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00007.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_5234_network/00008.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00008.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_5234_network/00008.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00008.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00000.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00000.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00001.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00001.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00001.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_clone/00001.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00002.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00002.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00003.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00003.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_clone/00003.png
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00004.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00004.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00004.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00005.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00005.png
new file mode 100644
index 000000000..c9222461c
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00005.png differ
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00006.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00006.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00006.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_clone/00006.png
diff --git a/tests/snapshots/nanox_transfer_ethereum_clone/00007.png b/tests/zemu/snapshots/nanox_transfer_ethereum_clone/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_ethereum_clone/00007.png
rename to tests/zemu/snapshots/nanox_transfer_ethereum_clone/00007.png
diff --git a/tests/zemu/snapshots/nanox_transfer_palm_network/00000.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_palm_network/00000.png differ
diff --git a/tests/snapshots/nanox_transfer_palm_network/00001.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00001.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00001.png
rename to tests/zemu/snapshots/nanox_transfer_palm_network/00001.png
diff --git a/tests/zemu/snapshots/nanox_transfer_palm_network/00002.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00002.png
new file mode 100644
index 000000000..0f18eeec9
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_palm_network/00002.png differ
diff --git a/tests/snapshots/nanox_transfer_palm_network/00003.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00003.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00003.png
rename to tests/zemu/snapshots/nanox_transfer_palm_network/00003.png
diff --git a/tests/snapshots/nanox_transfer_palm_network/00004.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00004.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00004.png
rename to tests/zemu/snapshots/nanox_transfer_palm_network/00004.png
diff --git a/tests/zemu/snapshots/nanox_transfer_palm_network/00005.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_palm_network/00005.png differ
diff --git a/tests/zemu/snapshots/nanox_transfer_palm_network/00006.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00006.png
new file mode 100644
index 000000000..c9222461c
Binary files /dev/null and b/tests/zemu/snapshots/nanox_transfer_palm_network/00006.png differ
diff --git a/tests/snapshots/nanox_transfer_palm_network/00007.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00007.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00007.png
rename to tests/zemu/snapshots/nanox_transfer_palm_network/00007.png
diff --git a/tests/snapshots/nanox_transfer_palm_network/00008.png b/tests/zemu/snapshots/nanox_transfer_palm_network/00008.png
similarity index 100%
rename from tests/snapshots/nanox_transfer_palm_network/00008.png
rename to tests/zemu/snapshots/nanox_transfer_palm_network/00008.png
diff --git a/tests/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00000.png b/tests/zemu/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00000.png
similarity index 100%
rename from tests/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00000.png
rename to tests/zemu/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00000.png
diff --git a/tests/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00001.png b/tests/zemu/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00001.png
similarity index 100%
rename from tests/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00001.png
rename to tests/zemu/snapshots/nanox_try_to_blind_sign_with_setting_disabled/00001.png
diff --git a/tests/src/approve.test.js b/tests/zemu/src/approve.test.js
similarity index 100%
rename from tests/src/approve.test.js
rename to tests/zemu/src/approve.test.js
diff --git a/tests/src/blind_compound_deposit.test.js b/tests/zemu/src/blind_compound_deposit.test.js
similarity index 100%
rename from tests/src/blind_compound_deposit.test.js
rename to tests/zemu/src/blind_compound_deposit.test.js
diff --git a/tests/src/chainid.test.js b/tests/zemu/src/chainid.test.js
similarity index 100%
rename from tests/src/chainid.test.js
rename to tests/zemu/src/chainid.test.js
diff --git a/tests/src/contract_data_warning.test.js b/tests/zemu/src/contract_data_warning.test.js
similarity index 100%
rename from tests/src/contract_data_warning.test.js
rename to tests/zemu/src/contract_data_warning.test.js
diff --git a/tests/src/eip1559.test.js b/tests/zemu/src/eip1559.test.js
similarity index 100%
rename from tests/src/eip1559.test.js
rename to tests/zemu/src/eip1559.test.js
diff --git a/tests/src/eip191.test.js b/tests/zemu/src/eip191.test.js
similarity index 87%
rename from tests/src/eip191.test.js
rename to tests/zemu/src/eip191.test.js
index 2223256b0..c54b01352 100644
--- a/tests/src/eip191.test.js
+++ b/tests/zemu/src/eip191.test.js
@@ -34,7 +34,7 @@ nano_models.forEach(function(model) {
 
         await waitForAppScreen(sim);
 
-        const rclicks = (model.letter == 'S') ? 6 : 4;
+        const rclicks = (model.letter == 'S') ? 8 : 4;
         await sim.navigateAndCompareSnapshots('.', model.name + '_eip191_nonascii', [rclicks, -1, 0]);
 
         await expect(tx).resolves.toEqual({
@@ -54,7 +54,14 @@ nano_models.forEach(function(model) {
 
         await waitForAppScreen(sim);
 
-        await sim.navigateAndCompareSnapshots('.', model.name + '_eip191_opensea', [7, -1, 0]);
+        if (model.letter == 'S')
+        {
+            await sim.navigateAndCompareSnapshots('.', model.name + '_eip191_opensea', [1, 5, 1, 6, 0, 1, -1, 0]);
+        }
+        else
+        {
+            await sim.navigateAndCompareSnapshots('.', model.name + '_eip191_opensea', [1, 5, 1, 2, 1, -1, 0]);
+        }
 
         await expect(tx).resolves.toEqual({
             "v": 28,
diff --git a/tests/src/erc1155.test.js b/tests/zemu/src/erc1155.test.js
similarity index 100%
rename from tests/src/erc1155.test.js
rename to tests/zemu/src/erc1155.test.js
diff --git a/tests/src/erc721.test.js b/tests/zemu/src/erc721.test.js
similarity index 100%
rename from tests/src/erc721.test.js
rename to tests/zemu/src/erc721.test.js
diff --git a/tests/src/send.test.js b/tests/zemu/src/send.test.js
similarity index 100%
rename from tests/src/send.test.js
rename to tests/zemu/src/send.test.js
diff --git a/tests/src/send_bsc.test.js b/tests/zemu/src/send_bsc.test.js
similarity index 100%
rename from tests/src/send_bsc.test.js
rename to tests/zemu/src/send_bsc.test.js
diff --git a/tests/src/send_etc.test.js b/tests/zemu/src/send_etc.test.js
similarity index 100%
rename from tests/src/send_etc.test.js
rename to tests/zemu/src/send_etc.test.js
diff --git a/tests/src/starkware.test.js b/tests/zemu/src/starkware.test.js
similarity index 100%
rename from tests/src/starkware.test.js
rename to tests/zemu/src/starkware.test.js
diff --git a/tests/src/test.fixture.js b/tests/zemu/src/test.fixture.js
similarity index 100%
rename from tests/src/test.fixture.js
rename to tests/zemu/src/test.fixture.js
diff --git a/tests/yarn.lock b/tests/zemu/yarn.lock
similarity index 99%
rename from tests/yarn.lock
rename to tests/zemu/yarn.lock
index 2ed8afaeb..b4b5395b3 100644
--- a/tests/yarn.lock
+++ b/tests/zemu/yarn.lock
@@ -2094,7 +2094,7 @@
 "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
-  integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
+  integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
 
 "@protobufjs/base64@^1.1.2":
   version "1.1.2"
@@ -2109,12 +2109,12 @@
 "@protobufjs/eventemitter@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
-  integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
+  integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
 
 "@protobufjs/fetch@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
-  integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
+  integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
   dependencies:
     "@protobufjs/aspromise" "^1.1.1"
     "@protobufjs/inquire" "^1.1.0"
@@ -2122,27 +2122,27 @@
 "@protobufjs/float@^1.0.2":
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
-  integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
+  integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
 
 "@protobufjs/inquire@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
-  integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
+  integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
 
 "@protobufjs/path@^1.1.2":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
-  integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
+  integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
 
 "@protobufjs/pool@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
-  integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
+  integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
 
 "@protobufjs/utf8@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
-  integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
+  integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
 
 "@sinonjs/commons@^1.7.0":
   version "1.8.3"
@@ -2231,14 +2231,14 @@
     "@types/istanbul-lib-report" "*"
 
 "@types/long@^4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
-  integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
+  integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
 
 "@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0":
-  version "15.6.1"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08"
-  integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==
+  version "18.0.0"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
+  integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -2881,9 +2881,9 @@ camelcase@^6.0.0:
   integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
 
 caniuse-lite@^1.0.30001219:
-  version "1.0.30001230"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
-  integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
+  version "1.0.30001312"
+  resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz"
+  integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==
 
 capture-exit@^2.0.0:
   version "2.0.0"
@@ -5607,9 +5607,9 @@ minimatch@^3.0.4:
     brace-expansion "^1.1.7"
 
 minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
-  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+  version "1.2.6"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+  integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
 
 mixin-deep@^1.2.0:
   version "1.3.2"
@@ -6043,9 +6043,9 @@ prompts@^2.0.1:
     sisteransi "^1.0.5"
 
 protobufjs@^6.10.0:
-  version "6.11.2"
-  resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b"
-  integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==
+  version "6.11.3"
+  resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74"
+  integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==
   dependencies:
     "@protobufjs/aspromise" "^1.1.2"
     "@protobufjs/base64" "^1.1.2"
@@ -6922,9 +6922,9 @@ throat@^5.0.0:
   integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
 
 tmpl@1.0.x:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
-  integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
+  integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
 
 to-fast-properties@^2.0.0:
   version "2.0.0"