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

Issue:
WIP: Fuzzing



Discussion / hints:

Fix patch:
diff --git a/.github/actions/commit-changes/action.yml b/.github/actions/commit-changes/action.yml
deleted file mode 100644
index f572b3244..000000000
--- a/.github/actions/commit-changes/action.yml
+++ /dev/null
@@ -1,119 +0,0 @@
-name: 'Commit and push if the version file has changed'
-
-inputs:
-  name:
-    description: 'The name of the commiter'
-    required: true
-    default: 'github-actions[bot]'
-  email:
-    description: 'The email of the commiter'
-    required: true
-    default: 'github-actions[bot]@users.noreply.github.com'
-  message:
-    description: 'The commit message'
-    required: true
-    default: 'New release version(s)'
-  files:
-    description: 'The file(s) to add in the commit'
-    required: true
-    default: '*'
-  directory:
-    description: 'The directory in which the action will be performed'
-    required: true
-    default: '.'
-  src_branch:
-    description: 'Checkout (or create) a specific branch before commit/push. Defaults to current branch'
-    required: false
-    default: ''
-  dst_branch:
-    description: 'Push the created commit on a specific branch. Defaults to current branch'
-    required: false
-    default: ''
-  secret:
-    description: 'A token allowing to push the commit on the repository'
-    required: true
-    default: '.'
-  repository:
-    description: 'The repository where to push'
-    required: true
-    default: ''
-
-runs:
-  using: 'composite'
-  steps:
-    - name: Commit the changes
-      id: commit
-      run: |
-        git config --global user.name ${{ inputs.name }}
-        ORIGIN="$(pwd)"
-        cd ${{ inputs.directory }}
-
-        CURRENT_BRANCH=${GITHUB_REF#refs/heads/};
-        # calculating source branch
-        if [ -n  "${{ inputs.src_branch }}" ]; \
-        then \
-          git switch ${{ inputs.src_branch }} 2>/dev/null || git switch -c ${{ inputs.src_branch }}; \
-          SRC_BRANCH=${{ inputs.src_branch }}; \
-        else \
-          SRC_BRANCH=`git branch --show-current`; \
-          if [ -z "$SRC_BRANCH" ]; \
-          then \
-            SRC_BRANCH=$CURRENT_BRANCH; \
-          fi \
-        fi
-
-        # calculating destination branch
-        if [ -n "${{ inputs.dst_branch }}" ]; \
-        then \
-          DST_BRANCH=${{ inputs.dst_branch }}; \
-        else \
-          DST_BRANCH=`git branch --show-current`; \
-          if [ -z "$DST_BRANCH" ]; \
-          then \
-            DST_BRANCH=$CURRENT_BRANCH; \
-          fi \
-        fi
-
-        echo "-----------------------------------------------------------"
-        echo "Initial repo status"
-        git status
-        # checking changes, commit if needed
-        CHANGES="$(git status --porcelain ${{ inputs.files }})"
-        if [ -n "${CHANGES}" ]; \
-        then \
-          echo -e "Changes:\n${CHANGES}"; \
-          git add ${{ inputs.files }}; \
-          echo "-----------------------------------------------------------"; \
-          echo "Repo status before commit"; \
-          git status; \
-          git commit -am "${{ inputs.message }}"; \
-        fi
-
-        # compute if a push is needed
-        if [ -n "${CHANGES}" -o "$SRC_BRANCH" != "$DST_BRANCH" ]; \
-        then \
-          PUSH="YES"; \
-        else \
-          PUSH="NO"; \
-        fi
-
-        git log -n 2
-        cd "${ORIGIN}"
-
-        echo " -- Env SRC_BRANCH: $SRC_BRANCH";
-        echo " -- Env DST_BRANCH: $DST_BRANCH";
-        echo " -- Env PUSH: $PUSH"
-        # exporting these variables for next steps
-        echo "##[set-output name=src_branch;]$(echo $SRC_BRANCH)";
-        echo "##[set-output name=dst_branch;]$(echo $DST_BRANCH)";
-        echo "##[set-output name=push;]$(echo $PUSH)";
-      shell: bash
-
-    - name: Push commit
-      if: steps.commit.outputs.push == 'YES'
-      uses: ad-m/github-push-action@master
-      with:
-        github_token: ${{ inputs.secret }}
-        branch: ${{ steps.commit.outputs.dst_branch }}
-        directory: ${{ inputs.directory }}
-        repository: ${{ inputs.repository }}
diff --git a/.github/workflows/codeql_checks.yml b/.github/workflows/codeql_checks.yml
index 75d1d1a38..d6bfebda4 100644
--- a/.github/workflows/codeql_checks.yml
+++ b/.github/workflows/codeql_checks.yml
@@ -28,6 +28,8 @@ jobs:
     steps:
       - name: Clone
         uses: actions/checkout@v4
+        with:
+          submodules: true
 
       - name: Initialize CodeQL
         uses: github/codeql-action/init@v3
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index 61d2c7ba8..1a0118b13 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -15,9 +15,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
+        with:
+          submodules: true
+
       - name: Check misspellings
         uses: codespell-project/actions-codespell@v2
         with:
           builtin: clear,rare
           check_filenames: true
-          path: src, src_bagl, src_common, src_features, src_nbgl, src_plugin_sdk, src_plugins, doc, client
+          path: src, src_bagl, src_features, src_nbgl, src_plugin_sdk, src_plugins, doc, client
diff --git a/.github/workflows/pr_on_all_plugins.yml b/.github/workflows/pr_on_all_plugins.yml
index 7618cdd6d..f24a66344 100644
--- a/.github/workflows/pr_on_all_plugins.yml
+++ b/.github/workflows/pr_on_all_plugins.yml
@@ -41,6 +41,7 @@ jobs:
       - name: Checkout SDK repository
         uses: actions/checkout@v4
         with:
+          submodules: true
           repository: LedgerHQ/ethereum-plugin-sdk
           ref: develop
       - name: Retrieve SDK reference
diff --git a/.github/workflows/sdk-generation.yml b/.github/workflows/sdk-generation.yml
deleted file mode 100644
index afefb3019..000000000
--- a/.github/workflows/sdk-generation.yml
+++ /dev/null
@@ -1,52 +0,0 @@
----
-name: Updating the SDK
-
-on:
-  workflow_dispatch:
-  push:
-    branches:
-      - master
-      - develop
-
-jobs:
-  updating_SDK:
-    name: Updating the SDK
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Clone
-        uses: actions/checkout@v4
-        with:
-          # by default the action uses fetch-depth = 1, which creates
-          # shallow repositories from which we can't push
-          fetch-depth: 0
-          submodules: recursive
-          # needed, else the push inside the action will use default credentials
-          # instead of provided ones
-          persist-credentials: false
-
-      - name: Build new SDK
-        run: ./tools/build_sdk.sh
-
-      - name: Extract branch name
-        shell: bash
-        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
-        id: extract_branch
-
-      - name: Commit & push changes in the SDK if any
-        uses: ./.github/actions/commit-changes
-        with:
-          name: 'ldg-github-ci'
-          directory: ethereum-plugin-sdk
-          dst_branch: ${{ steps.extract_branch.outputs.branch }}
-          message: "[update] Branch ${{ steps.extract_branch.outputs.branch }} | Commit ${GITHUB_SHA}"
-          secret: ${{ secrets.CI_BOT_TOKEN }}
-          repository: LedgerHQ/ethereum-plugin-sdk
-
-      - name: Create SDK update pull request
-        uses: peter-evans/create-pull-request@v4
-        with:
-          branch: sdk/update-submodule
-          delete-branch: true
-          title: Update the SDK submodule
-          reviewers: apailler-ledger
diff --git a/.gitignore b/.gitignore
index 6b3139a86..20f25ff19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,17 +3,15 @@ bin/
 debug/
 build/
 
+# Unit tests and code coverage
+tests/unit/build/
+tests/unit/coverage/
+tests/unit/coverage.*
+
 # Python
 venv/
 *.pyc
 __version__.py
 
-# JS
-tests/node_modules
-tests/lib
-tests/yarn-error.log
-tests/elfs/*
-tests/snapshots-tmp
-
 .vscode
 .idea
diff --git a/Makefile b/Makefile
index a09d220f9..c5a912f3e 100644
--- a/Makefile
+++ b/Makefile
@@ -21,289 +21,39 @@ endif
 
 include $(BOLOS_SDK)/Makefile.defines
 
-DEFINES_LIB = USE_LIB_ETHEREUM
-APP_LOAD_PARAMS = --curve secp256k1 $(COMMON_LOAD_PARAMS)
-# Allow the app to use path 45 for multi-sig (see BIP45).
-APP_LOAD_PARAMS += --path "45'"
-# Samsung temporary implementation for wallet ID on 0xda7aba5e/0xc1a551c5
-APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
-
-##################
-# Define Version #
-##################
-
-APPVERSION_M = 1
-APPVERSION_N = 11
-APPVERSION_P = 0
-APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-dev
-APP_LOAD_FLAGS = --appFlags 0xa40 --dep Ethereum:$(APPVERSION)
-
-#########################
-# Set Chain environment #
-#########################
+########################################
+#        Mandatory configuration       #
+########################################
 
 ifeq ($(CHAIN),)
     CHAIN = ethereum
+    # Temporary definition to ensure VSCode extension works... To be cleaned later
+    APPNAME = Ethereum
 endif
 
 SUPPORTED_CHAINS = $(shell find makefile_conf/chain/ -type f -name '*.mk'| sed 's/.*\/\(.*\).mk/\1/g' | sort)
-
-# Check if chain is available
-ifeq ($(shell test -s ./makefile_conf/chain/$(CHAIN).mk && echo -n yes), yes)
-    include ./makefile_conf/chain/$(CHAIN).mk
-else
-    $(error Unsupported CHAIN - use $(SUPPORTED_CHAINS))
-endif
-CFLAGS += -DAPPNAME=\"$(APPNAME)\"
-DEFINES += CHAINID_COINNAME=\"$(TICKER)\" CHAIN_ID=$(CHAIN_ID)
-
-#########
-# Other #
-#########
-
-APP_LOAD_PARAMS += $(APP_LOAD_FLAGS) --path "44'/1'"
-DEFINES += $(DEFINES_LIB)
-
-#prepare hsm generation
-ifeq ($(TARGET_NAME),TARGET_NANOS)
-    ICONNAME = icons/nanos_app_chain_$(CHAIN_ID).gif
-else ifeq ($(TARGET_NAME),TARGET_STAX)
-    ICONNAME = icons/stax_app_chain_$(CHAIN_ID).gif
-    DEFINES += ICONGLYPH=C_stax_chain_$(CHAIN_ID)_64px
-    DEFINES += ICONBITMAP=C_stax_chain_$(CHAIN_ID)_64px_bitmap
-    DEFINES += ICONGLYPH_SMALL=C_stax_chain_$(CHAIN_ID)
-    GLYPH_FILES += $(ICONNAME)
-else
-    ICONNAME = icons/nanox_app_chain_$(CHAIN_ID).gif
-endif
-
-################
-# Default rule #
-################
-all: default
-
-############
-# Platform #
-############
-
-DEFINES += OS_IO_SEPROXYHAL
-DEFINES += HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U
-DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
-DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P)
-DEFINES += BUILD_YEAR=\"$(shell date +%Y)\"
-
-# U2F
-DEFINES += HAVE_U2F HAVE_IO_U2F
-DEFINES += U2F_PROXY_MAGIC=\"w0w\"
-DEFINES += USB_SEGMENT_SIZE=64
-DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20
-DEFINES += APPVERSION=\"$(APPVERSION)\"
-
-#WEBUSB_URL = www.ledgerwallet.com
-#DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g")
-
-DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""
-
-ifneq (,$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX))
-    DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000
-    DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE
-    SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
-endif
-
-ifeq ($(TARGET_NAME),TARGET_NANOS)
-    DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
-else
-    DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
-endif
-
-ifeq  ($(TARGET_NAME),TARGET_STAX)
-    DEFINES += NBGL_QRCODE
-    SDK_SOURCE_PATH += qrcode
-else
-    DEFINES += HAVE_BAGL
-    DEFINES += HAVE_UX_FLOW
-    ifeq ($(TARGET_NAME),TARGET_NANOS)
-        DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=32
-    else
-        DEFINES += HAVE_GLO096
-        DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64
-        DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
-        DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
-        DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
-        DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
-    endif
-endif
-
-####################
-# Enabled Features #
-####################
-
-# Enables direct data signing without having to specify it in the settings. Useful when testing with speculos.
-ALLOW_DATA ?= 0
-ifneq ($(ALLOW_DATA),0)
-    DEFINES += HAVE_ALLOW_DATA
-endif
-
-# Bypass the signature verification for setExternalPlugin, setPlugin, provideERC20TokenInfo and provideNFTInfo calls
-BYPASS_SIGNATURES ?= 0
-ifneq ($(BYPASS_SIGNATURES),0)
-    DEFINES += HAVE_BYPASS_SIGNATURES
-endif
-
-# Enable the SET_PLUGIN test key
-SET_PLUGIN_TEST_KEY ?= 0
-ifneq ($(SET_PLUGIN_TEST_KEY),0)
-    DEFINES += HAVE_SET_PLUGIN_TEST_KEY
-endif
-
-# NFTs
-ifneq ($(TARGET_NAME),TARGET_NANOS)
-    DEFINES	+= HAVE_NFT_SUPPORT
-    NFT_TEST_KEY ?= 0
-    ifneq ($(NFT_TEST_KEY),0)
-        DEFINES += HAVE_NFT_TEST_KEY
-    endif
-    NFT_STAGING_KEY ?= 0
-    ifneq ($(NFT_STAGING_KEY),0)
-        # Key used by the staging backend
-        DEFINES += HAVE_NFT_STAGING_KEY
-    endif
-endif
-ifneq (,$(filter $(DEFINES),HAVE_NFT_TEST_KEY))
-    ifneq (, $(filter $(DEFINES),HAVE_NFT_STAGING_KEY))
-        $(error Multiple alternative NFT keys set at once)
-    endif
-endif
-
-# Dynamic memory allocator
-ifneq ($(TARGET_NAME),TARGET_NANOS)
-    DEFINES += HAVE_DYN_MEM_ALLOC
-endif
-
-# EIP-712
-ifneq ($(TARGET_NAME),TARGET_NANOS)
-    DEFINES	+= HAVE_EIP712_FULL_SUPPORT
-endif
-
-# CryptoAssetsList key
-CAL_TEST_KEY ?= 0
-ifneq ($(CAL_TEST_KEY),0)
-    # Key used in our test framework
-    DEFINES += HAVE_CAL_TEST_KEY
-endif
-CAL_STAGING_KEY ?= 0
-ifneq ($(CAL_STAGING_KEY),0)
-    # Key used by the staging CAL
-    DEFINES += HAVE_CAL_STAGING_KEY
-endif
-ifneq (,$(filter $(DEFINES),HAVE_CAL_TEST_KEY))
-    ifneq (, $(filter $(DEFINES),HAVE_CAL_STAGING_KEY))
-        # Can't use both the staging and testing keys
-        $(error Multiple alternative CAL keys set at once)
-    endif
-endif
-
-# ENS
-ifneq ($(TARGET_NAME),TARGET_NANOS)
-    DEFINES += HAVE_DOMAIN_NAME
-    DOMAIN_NAME_TEST_KEY ?= 0
-    ifneq ($(DOMAIN_NAME_TEST_KEY),0)
-        DEFINES += HAVE_DOMAIN_NAME_TEST_KEY
-    endif
+ifneq ($(CHAIN),$(filter $(CHAIN),$(SUPPORTED_CHAINS)))
+    $(error Unsupported CHAIN. Use one of: $(SUPPORTED_CHAINS))
 endif
+include ./makefile_conf/chain/$(CHAIN).mk
 
-# Enabling debug PRINTF
-ifneq ($(DEBUG),0)
-    DEFINES += HAVE_STACK_OVERFLOW_CHECK
-    ifeq ($(TARGET_NAME),TARGET_NANOS)
-        DEFINES += HAVE_PRINTF PRINTF=screen_printf
-    else
-        DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
-    endif
-else
-    DEFINES += PRINTF\(...\)=
-endif
-
-ifneq ($(NOCONSENT),)
-    DEFINES += NO_CONSENT
-endif
-
-##############
-#  Compiler  #
-##############
-
-ifneq ($(BOLOS_ENV),)
-    $(info BOLOS_ENV=$(BOLOS_ENV))
-    CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/
-    GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
-else
-    $(info BOLOS_ENV is not set: falling back to CLANGPATH and GCCPATH)
-endif
-ifeq ($(CLANGPATH),)
-    $(info CLANGPATH is not set: clang will be used from PATH)
-endif
-ifeq ($(GCCPATH),)
-    $(info GCCPATH is not set: arm-none-eabi-* will be used from PATH)
-endif
-
-CC := $(CLANGPATH)clang
-CFLAGS += -Wno-format-invalid-specifier -Wno-format-extra-args
-AS := $(GCCPATH)arm-none-eabi-gcc
-LD := $(GCCPATH)arm-none-eabi-gcc
-LDLIBS += -lm -lgcc -lc
-
-# import rules to compile glyphs(/pone)
-include $(BOLOS_SDK)/Makefile.glyphs
+APPVERSION_M = 1
+APPVERSION_N = 11
+APPVERSION_P = 0
+APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-dev
 
-### variables processed by the common makefile.rules of the SDK to grab source files and include dirs
-APP_SOURCE_PATH += src_common src src_features src_plugins
-SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f
-ifeq  ($(TARGET_NAME),TARGET_STAX)
+# Application source files
+APP_SOURCE_PATH += src src_features src_plugins
+ifeq ($(TARGET_NAME),TARGET_STAX)
     APP_SOURCE_PATH += src_nbgl
 else
-    SDK_SOURCE_PATH += lib_ux
     APP_SOURCE_PATH += src_bagl
 endif
-
-# Allow usage of function from lib_standard_app/crypto_helpers.c
+APP_SOURCE_FILES += $(filter-out ./ethereum-plugin-sdk/src/main.c, $(wildcard ./ethereum-plugin-sdk/src/*.c))
+INCLUDES_PATH += ./ethereum-plugin-sdk/src
 APP_SOURCE_FILES += ${BOLOS_SDK}/lib_standard_app/crypto_helpers.c
-
-### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed
-ifeq ($(CHAIN),ethereum)
-    ifneq ($(shell git submodule status | grep '^[-+]'),)
-        $(info INFO: Need to reinitialize git submodules)
-        $(shell git submodule update --init)
-    endif
-
-    # rebuild SDK
-    $(shell ./tools/build_sdk.sh)
-
-    # check if a difference is noticed (fail if it happens in CI build)
-    ifneq ($(shell git status | grep 'ethereum-plugin-sdk'),)
-        ifneq ($(JENKINS_URL),)
-            $(error ERROR: please update ethereum-plugin-sdk submodule first)
-        else
-            $(warning WARNING: please update ethereum-plugin-sdk submodule first)
-        endif
-    endif
-endif
-
-load: all
-	python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
-
-delete:
-	python3 -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)
-
-install_tests:
-	cd tests/zemu/ && (yarn install || sudo yarn install)
-
-run_tests:
-	cd tests/zemu/ && (yarn test || sudo yarn test)
-
-test: install_tests run_tests
-
-unit-test:
-	make -C tests/unit
+APP_SOURCE_FILES += ${BOLOS_SDK}/lib_standard_app/format.c
+INCLUDES_PATH += ${BOLOS_SDK}/lib_standard_app
 
 ifeq ($(TARGET_NAME),TARGET_STAX)
 NETWORK_ICONS_FILE = $(GEN_SRC_DIR)/net_icons.gen.c
@@ -315,11 +65,102 @@ $(NETWORK_ICONS_FILE):
 APP_SOURCE_FILES += $(NETWORK_ICONS_FILE)
 endif
 
-# import generic rules from the sdk
-include $(BOLOS_SDK)/Makefile.rules
+# Application icons following guidelines:
+# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon
+ICON_NANOS = icons/nanos_app_chain_$(CHAIN_ID).gif
+ICON_NANOX = icons/nanox_app_chain_$(CHAIN_ID).gif
+ICON_NANOSP = icons/nanox_app_chain_$(CHAIN_ID).gif
+ICON_STAX = icons/stax_app_chain_$(CHAIN_ID).gif
 
-#add dependency on custom makefile filename
-dep/%.d: %.c Makefile
+#prepare hsm generation
+ifeq ($(TARGET_NAME),TARGET_STAX)
+    DEFINES += ICONGLYPH=C_stax_chain_$(CHAIN_ID)_64px
+    DEFINES += ICONBITMAP=C_stax_chain_$(CHAIN_ID)_64px_bitmap
+    DEFINES += ICONGLYPH_SMALL=C_stax_chain_$(CHAIN_ID)
+endif
+
+
+# Application allowed derivation curves.
+# Possibles curves are: secp256k1, secp256r1, ed25519 and bls12381g1
+# If your app needs it, you can specify multiple curves by using:
+# `CURVE_APP_LOAD_PARAMS = <curve1> <curve2>`
+CURVE_APP_LOAD_PARAMS += secp256k1
+
+# Application allowed derivation paths.
+# You should request a specific path for your app.
+# This serve as an isolation mechanism.
+# Most application will have to request a path according to the BIP-0044
+# and SLIP-0044 standards.
+# If your app needs it, you can specify multiple path by using:
+# `PATH_APP_LOAD_PARAMS = "44'/1'" "45'/1'"`
+PATH_APP_LOAD_PARAMS += "45'" "44'/1'"
+
+# Setting to allow building variant applications
+# - <VARIANT_PARAM> is the name of the parameter which should be set
+#   to specify the variant that should be build.
+# - <VARIANT_VALUES> a list of variant that can be build using this app code.
+#   * It must at least contains one value.
+#   * Values can be the app ticker or anything else but should be unique.
+VARIANT_PARAM = CHAIN
+VARIANT_VALUES = $(SUPPORTED_CHAINS)
+
+# Activate dependency only for specific CHAIN
+ifneq ($(CHAIN),ethereum)
+    DEP_APP_LOAD_PARAMS = Ethereum:$(APPVERSION)
+    DEFINES_LIB = USE_LIB_ETHEREUM
+endif
+
+# Enabling DEBUG flag will enable PRINTF and disable optimizations
+#DEBUG = 1
+
+########################################
+#     Application custom permissions   #
+########################################
+# See SDK `include/appflags.h` for the purpose of each permission
+#HAVE_APPLICATION_FLAG_DERIVE_MASTER = 1
+HAVE_APPLICATION_FLAG_GLOBAL_PIN = 1
+HAVE_APPLICATION_FLAG_BOLOS_SETTINGS = 1
+HAVE_APPLICATION_FLAG_LIBRARY = 1
+
+########################################
+# Application communication interfaces #
+########################################
+ENABLE_BLUETOOTH = 1
+#ENABLE_NFC = 1
+
+########################################
+#         NBGL custom features         #
+########################################
+ENABLE_NBGL_QRCODE = 1
+#ENABLE_NBGL_KEYBOARD = 1
+#ENABLE_NBGL_KEYPAD = 1
+
+########################################
+#          Features disablers          #
+########################################
+# These advanced settings allow to disable some feature that are by
+# default enabled in the SDK `Makefile.standard_app`.
+DISABLE_STANDARD_APP_FILES = 1
+#DISABLE_DEFAULT_IO_SEPROXY_BUFFER_SIZE = 1 # To allow custom size declaration
+#DISABLE_STANDARD_APP_DEFINES = 1 # Will set all the following disablers
+#DISABLE_STANDARD_SNPRINTF = 1
+#DISABLE_STANDARD_USB = 1
+#DISABLE_STANDARD_WEBUSB = 1
+#DISABLE_STANDARD_BAGL_UX_FLOW = 1
+#DISABLE_DEBUG_LEDGER_ASSERT = 1
+#DISABLE_DEBUG_THROW = 1
+
+########################################
+#        Main app configuration        #
+########################################
+
+DEFINES += CHAINID_COINNAME=\"$(TICKER)\" CHAIN_ID=$(CHAIN_ID)
+DEFINES += BUILD_YEAR=\"$(shell date +%Y)\"
+
+# Enabled Features #
+include makefile_conf/features.mk
+
+#########################
 
-listvariants:
-	@echo VARIANTS CHAIN $(SUPPORTED_CHAINS)
+# Import generic rules from the SDK
+include $(BOLOS_SDK)/Makefile.standard_app
diff --git a/README.md b/README.md
index 7cc7fc75e..2ba3b12f4 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,12 @@ If you prefer using a terminal to perform the steps manually, you can use the gu
 
 Setup a compilation environment by following the [shell with docker approach](#with-a-terminal).
 
+Be sure you checkout the submodule:
+
+```shell
+git submodule update --init
+```
+
 From inside the container, use the following command to build the app:
 
 ```shell
diff --git a/icons/nanos_app_chain_14.gif b/icons/nanos_app_chain_14.gif
deleted file mode 100644
index b96842bad..000000000
Binary files a/icons/nanos_app_chain_14.gif and /dev/null differ
diff --git a/icons/nanos_app_chain_16.gif b/icons/nanos_app_chain_16.gif
deleted file mode 100644
index f83753426..000000000
Binary files a/icons/nanos_app_chain_16.gif and /dev/null differ
diff --git a/icons/nanos_app_chain_3.gif b/icons/nanos_app_chain_3.gif
deleted file mode 100644
index 8f8fa310b..000000000
Binary files a/icons/nanos_app_chain_3.gif and /dev/null differ
diff --git a/icons/nanos_app_chain_5.gif b/icons/nanos_app_chain_5.gif
deleted file mode 100644
index 8f8fa310b..000000000
Binary files a/icons/nanos_app_chain_5.gif and /dev/null differ
diff --git a/icons/nanox_app_chain_14.gif b/icons/nanox_app_chain_14.gif
deleted file mode 100644
index 3a617f8e9..000000000
Binary files a/icons/nanox_app_chain_14.gif and /dev/null differ
diff --git a/icons/nanox_app_chain_16.gif b/icons/nanox_app_chain_16.gif
deleted file mode 100644
index 34cc7f561..000000000
Binary files a/icons/nanox_app_chain_16.gif and /dev/null differ
diff --git a/icons/nanox_app_chain_3.gif b/icons/nanox_app_chain_3.gif
deleted file mode 100644
index d70e8a726..000000000
Binary files a/icons/nanox_app_chain_3.gif and /dev/null differ
diff --git a/icons/nanox_app_chain_5.gif b/icons/nanox_app_chain_5.gif
deleted file mode 100644
index d70e8a726..000000000
Binary files a/icons/nanox_app_chain_5.gif and /dev/null differ
diff --git a/icons/stax_app_chain_14.gif b/icons/stax_app_chain_14.gif
deleted file mode 100644
index 4d1a0f875..000000000
Binary files a/icons/stax_app_chain_14.gif and /dev/null differ
diff --git a/icons/stax_app_chain_16.gif b/icons/stax_app_chain_16.gif
deleted file mode 100644
index 2f77deea1..000000000
Binary files a/icons/stax_app_chain_16.gif and /dev/null differ
diff --git a/icons/stax_app_chain_3.gif b/icons/stax_app_chain_3.gif
deleted file mode 100644
index 4c7a5a0e7..000000000
Binary files a/icons/stax_app_chain_3.gif and /dev/null differ
diff --git a/icons/stax_app_chain_5.gif b/icons/stax_app_chain_5.gif
deleted file mode 100644
index 95c819d26..000000000
Binary files a/icons/stax_app_chain_5.gif and /dev/null differ
diff --git a/makefile_conf/chain/akroma.mk b/makefile_conf/chain/akroma.mk
index 0426bdb52..6da1b1720 100644
--- a/makefile_conf/chain/akroma.mk
+++ b/makefile_conf/chain/akroma.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/200625'"
+PATH_APP_LOAD_PARAMS += "44'/200625'"
 TICKER = "AKA"
 CHAIN_ID = 200625
 APPNAME = "Akroma"
diff --git a/makefile_conf/chain/apothemnetwork.mk b/makefile_conf/chain/apothemnetwork.mk
index 57dc45ba5..34464823d 100644
--- a/makefile_conf/chain/apothemnetwork.mk
+++ b/makefile_conf/chain/apothemnetwork.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/550'"
+PATH_APP_LOAD_PARAMS += "44'/550'"
 TICKER = "TXDC"
 CHAIN_ID = 51
 APPNAME = "ApothemNetwork"
diff --git a/makefile_conf/chain/artis_sigma1.mk b/makefile_conf/chain/artis_sigma1.mk
index 1539ccc2a..bcf77a606 100644
--- a/makefile_conf/chain/artis_sigma1.mk
+++ b/makefile_conf/chain/artis_sigma1.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/246529'"
+PATH_APP_LOAD_PARAMS += "44'/246529'"
 TICKER = "ATS"
 CHAIN_ID = 246529
 APPNAME = "ARTIS sigma1"
diff --git a/makefile_conf/chain/artis_tau1.mk b/makefile_conf/chain/artis_tau1.mk
index 720f50625..6aacfccbd 100644
--- a/makefile_conf/chain/artis_tau1.mk
+++ b/makefile_conf/chain/artis_tau1.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/246785'"
+PATH_APP_LOAD_PARAMS += "44'/246785'"
 TICKER = "ATS"
 CHAIN_ID = 246785
 APPNAME = "ARTIS tau1"
diff --git a/makefile_conf/chain/astar.mk b/makefile_conf/chain/astar.mk
index 8914d3800..e1523260c 100644
--- a/makefile_conf/chain/astar.mk
+++ b/makefile_conf/chain/astar.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/810'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/810'" "44'/60'"
 TICKER = "ASTR"
 CHAIN_ID = 592
 APPNAME = "Astar Polkadot EVM"
diff --git a/makefile_conf/chain/atheios.mk b/makefile_conf/chain/atheios.mk
index 77a73d731..3ecb1154c 100644
--- a/makefile_conf/chain/atheios.mk
+++ b/makefile_conf/chain/atheios.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/1620'"
+PATH_APP_LOAD_PARAMS += "44'/1620'"
 TICKER = "ATH"
 CHAIN_ID = 1620
 APPNAME = "Atheios"
diff --git a/makefile_conf/chain/bsc.mk b/makefile_conf/chain/bsc.mk
index e3c9f6a71..3a478411b 100644
--- a/makefile_conf/chain/bsc.mk
+++ b/makefile_conf/chain/bsc.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "BNB"
 CHAIN_ID = 56
 APPNAME = "Binance Smart Chain"
diff --git a/makefile_conf/chain/bttc.mk b/makefile_conf/chain/bttc.mk
index 64513371a..fdb1781fb 100644
--- a/makefile_conf/chain/bttc.mk
+++ b/makefile_conf/chain/bttc.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "BTT"
 CHAIN_ID = 199
 APPNAME = "BTTC"
diff --git a/makefile_conf/chain/callisto.mk b/makefile_conf/chain/callisto.mk
index 5919f3fbd..f8fe7889f 100644
--- a/makefile_conf/chain/callisto.mk
+++ b/makefile_conf/chain/callisto.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/820'"
+PATH_APP_LOAD_PARAMS += "44'/820'"
 TICKER = "CLO"
 CHAIN_ID = 820
 APPNAME = "Callisto"
diff --git a/makefile_conf/chain/conflux_espace.mk b/makefile_conf/chain/conflux_espace.mk
index 8bc8c9abb..2dd6a4b7f 100644
--- a/makefile_conf/chain/conflux_espace.mk
+++ b/makefile_conf/chain/conflux_espace.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "CFX"
 CHAIN_ID = 1030
 APPNAME = "Conflux eSpace"
diff --git a/makefile_conf/chain/cube.mk b/makefile_conf/chain/cube.mk
index 614036d7f..72b90bd38 100644
--- a/makefile_conf/chain/cube.mk
+++ b/makefile_conf/chain/cube.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "CUBE"
 CHAIN_ID = 1818
 APPNAME = "Cube"
diff --git a/makefile_conf/chain/dexon.mk b/makefile_conf/chain/dexon.mk
index 7cd36b73a..7985c532a 100644
--- a/makefile_conf/chain/dexon.mk
+++ b/makefile_conf/chain/dexon.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/237'"
+PATH_APP_LOAD_PARAMS += "44'/237'"
 TICKER = "DXN"
 CHAIN_ID = 237
 APPNAME = "DEXON"
diff --git a/makefile_conf/chain/ellaism.mk b/makefile_conf/chain/ellaism.mk
index 27df5db75..e3396a8d3 100644
--- a/makefile_conf/chain/ellaism.mk
+++ b/makefile_conf/chain/ellaism.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/163'"
+PATH_APP_LOAD_PARAMS += "44'/163'"
 TICKER = "ELLA"
 CHAIN_ID = 64
 APPNAME = "Ellaism"
diff --git a/makefile_conf/chain/energywebchain.mk b/makefile_conf/chain/energywebchain.mk
index 6de07e2c3..6dbf94fcc 100644
--- a/makefile_conf/chain/energywebchain.mk
+++ b/makefile_conf/chain/energywebchain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/246'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/246'" "44'/60'"
 TICKER = "EWT"
 CHAIN_ID = 246
 APPNAME = "EnergyWebChain"
diff --git a/makefile_conf/chain/ether1.mk b/makefile_conf/chain/ether1.mk
index 188558632..7641aa1bd 100644
--- a/makefile_conf/chain/ether1.mk
+++ b/makefile_conf/chain/ether1.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/1313114'"
+PATH_APP_LOAD_PARAMS += "44'/1313114'"
 TICKER = "ETHO"
 CHAIN_ID = 1313114
 APPNAME = "Ether-1"
diff --git a/makefile_conf/chain/ethereum.mk b/makefile_conf/chain/ethereum.mk
index 993c9306d..a30fd11d1 100644
--- a/makefile_conf/chain/ethereum.mk
+++ b/makefile_conf/chain/ethereum.mk
@@ -1,11 +1,10 @@
 # Lock the application on its standard path for 1.5. Please complain if non compliant
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "ETH"
 CHAIN_ID = 1
 # Allow to derive ETH 2 public keys
-APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1
+PATH_APP_LOAD_PARAMS += "12381/3600"
+CURVE_APP_LOAD_PARAMS += bls12381g1
 DEFINES += HAVE_ETH2
 APPNAME = "Ethereum"
-DEFINES_LIB=
 DEFINES += HAVE_BOLOS_APP_STACK_CANARY
-APP_LOAD_FLAGS=--appFlags 0xa40
diff --git a/makefile_conf/chain/ethereum_classic.mk b/makefile_conf/chain/ethereum_classic.mk
index 5cc1760c7..1aea2af95 100644
--- a/makefile_conf/chain/ethereum_classic.mk
+++ b/makefile_conf/chain/ethereum_classic.mk
@@ -1,5 +1,5 @@
 # Also allows ETC to access the ETH derivation path to recover forked assets
-APP_LOAD_PARAMS += --path "44'/61'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/61'" "44'/60'"
 TICKER = "ETC"
 CHAIN_ID = 61
 APPNAME = "Ethereum Classic"
diff --git a/makefile_conf/chain/ethergem.mk b/makefile_conf/chain/ethergem.mk
index 09d3855a4..a1f56ead6 100644
--- a/makefile_conf/chain/ethergem.mk
+++ b/makefile_conf/chain/ethergem.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/1987'"
+PATH_APP_LOAD_PARAMS += "44'/1987'"
 TICKER = "EGEM"
 CHAIN_ID = 1987
 APPNAME = "EtherGem"
diff --git a/makefile_conf/chain/ethersocial.mk b/makefile_conf/chain/ethersocial.mk
index 95e153c8e..c1586b27e 100644
--- a/makefile_conf/chain/ethersocial.mk
+++ b/makefile_conf/chain/ethersocial.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/31102'"
+PATH_APP_LOAD_PARAMS += "44'/31102'"
 TICKER = "ESN"
 CHAIN_ID = 31102
 APPNAME = "Ethersocial"
diff --git a/makefile_conf/chain/expanse.mk b/makefile_conf/chain/expanse.mk
index 737ec439f..24972b0b6 100644
--- a/makefile_conf/chain/expanse.mk
+++ b/makefile_conf/chain/expanse.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/40'"
+PATH_APP_LOAD_PARAMS += "44'/40'"
 TICKER = "EXP"
 CHAIN_ID = 2
 APPNAME = "Expanse"
diff --git a/makefile_conf/chain/flare.mk b/makefile_conf/chain/flare.mk
deleted file mode 100644
index e8ecf3b82..000000000
--- a/makefile_conf/chain/flare.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
-TICKER = "FLR"
-CHAIN_ID = 14
-
-# Pending review parameters
-APP_LOAD_PARAMS += --tlvraw 9F:01
-DEFINES += HAVE_PENDING_REVIEW_SCREEN
-
-APPNAME = "Flare"
diff --git a/makefile_conf/chain/flare_coston.mk b/makefile_conf/chain/flare_coston.mk
deleted file mode 100644
index f8f5ed229..000000000
--- a/makefile_conf/chain/flare_coston.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
-TICKER = "FLR"
-CHAIN_ID = 16
-APPNAME = "Flare Coston"
diff --git a/makefile_conf/chain/gochain.mk b/makefile_conf/chain/gochain.mk
index b24e64e6a..ed51bdc3c 100644
--- a/makefile_conf/chain/gochain.mk
+++ b/makefile_conf/chain/gochain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/6060'"
+PATH_APP_LOAD_PARAMS += "44'/6060'"
 TICKER = "GO"
 CHAIN_ID = 60
 APPNAME = "GoChain"
diff --git a/makefile_conf/chain/goerli.mk b/makefile_conf/chain/goerli.mk
deleted file mode 100644
index c01e6c9b8..000000000
--- a/makefile_conf/chain/goerli.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-APP_LOAD_PARAMS += --path "44'/60'"
-TICKER = "ETH"
-CHAIN_ID = 5
-# Allow to derive ETH 2 public keys
-APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1
-DEFINES += HAVE_ETH2
-APPNAME = "Eth Goerli"
-DEFINES_LIB=
-DEFINES += HAVE_BOLOS_APP_STACK_CANARY
-APP_LOAD_FLAGS=--appFlags 0xa40
diff --git a/makefile_conf/chain/hpb.mk b/makefile_conf/chain/hpb.mk
index 03fc0056e..baf819bfc 100644
--- a/makefile_conf/chain/hpb.mk
+++ b/makefile_conf/chain/hpb.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/269'"
+PATH_APP_LOAD_PARAMS += "44'/269'"
 TICKER = "HPB"
 CHAIN_ID = 269
 APPNAME = "HPB"
diff --git a/makefile_conf/chain/id4good.mk b/makefile_conf/chain/id4good.mk
index 4abac3043..79439e425 100644
--- a/makefile_conf/chain/id4good.mk
+++ b/makefile_conf/chain/id4good.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/161803'"
+PATH_APP_LOAD_PARAMS += "44'/161803'"
 TICKER = "A4G"
 CHAIN_ID = 846000
 APPNAME = "ID4Good"
diff --git a/makefile_conf/chain/kardiachain.mk b/makefile_conf/chain/kardiachain.mk
index 8ee40becf..5d73e4500 100644
--- a/makefile_conf/chain/kardiachain.mk
+++ b/makefile_conf/chain/kardiachain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "KAI"
 CHAIN_ID = 24
 APPNAME = "KardiaChain"
diff --git a/makefile_conf/chain/meter.mk b/makefile_conf/chain/meter.mk
index cb4554b0d..2089edcf5 100644
--- a/makefile_conf/chain/meter.mk
+++ b/makefile_conf/chain/meter.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "MTR"
 CHAIN_ID = 82
 APPNAME = "Meter"
diff --git a/makefile_conf/chain/mix.mk b/makefile_conf/chain/mix.mk
index 6d96ce796..52bbe2e2d 100644
--- a/makefile_conf/chain/mix.mk
+++ b/makefile_conf/chain/mix.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/76'"
+PATH_APP_LOAD_PARAMS += "44'/76'"
 TICKER = "MIX"
 CHAIN_ID = 76
 APPNAME = "Mix"
diff --git a/makefile_conf/chain/moonbeam.mk b/makefile_conf/chain/moonbeam.mk
index 963ee6377..edf4c3f50 100644
--- a/makefile_conf/chain/moonbeam.mk
+++ b/makefile_conf/chain/moonbeam.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'" --path "44'/1284'"
+PATH_APP_LOAD_PARAMS += "44'/60'" "44'/1284'"
 TICKER = "GLMR"
 CHAIN_ID = 1284
 APPNAME = "Moonbeam"
diff --git a/makefile_conf/chain/moonriver.mk b/makefile_conf/chain/moonriver.mk
index 5c9391e5b..a777fe02e 100644
--- a/makefile_conf/chain/moonriver.mk
+++ b/makefile_conf/chain/moonriver.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'" --path "44'/1285'"
+PATH_APP_LOAD_PARAMS += "44'/60'" "44'/1285'"
 TICKER = "MOVR"
 CHAIN_ID = 1285
 APPNAME = "Moonriver"
diff --git a/makefile_conf/chain/multivac.mk b/makefile_conf/chain/multivac.mk
index c5b527047..1fe26f946 100644
--- a/makefile_conf/chain/multivac.mk
+++ b/makefile_conf/chain/multivac.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "MTV"
 CHAIN_ID = 62621
 APPNAME = "MultiVAC"
diff --git a/makefile_conf/chain/musicoin.mk b/makefile_conf/chain/musicoin.mk
index 0c530d762..45238456c 100644
--- a/makefile_conf/chain/musicoin.mk
+++ b/makefile_conf/chain/musicoin.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/184'"
+PATH_APP_LOAD_PARAMS += "44'/184'"
 TICKER = "MUSIC"
 CHAIN_ID = 7762959
 APPNAME = "Musicoin"
diff --git a/makefile_conf/chain/oasys.mk b/makefile_conf/chain/oasys.mk
index 7fc384faf..b75afc985 100644
--- a/makefile_conf/chain/oasys.mk
+++ b/makefile_conf/chain/oasys.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/685'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/685'" "44'/60'"
 TICKER = "OAS"
 CHAIN_ID = 248
 APPNAME = "Oasys"
diff --git a/makefile_conf/chain/okc.mk b/makefile_conf/chain/okc.mk
index 9fdd4aa24..13e0f50a7 100644
--- a/makefile_conf/chain/okc.mk
+++ b/makefile_conf/chain/okc.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "OKT"
 CHAIN_ID = 66
 APPNAME = "OKXChain"
diff --git a/makefile_conf/chain/pirl.mk b/makefile_conf/chain/pirl.mk
index fec941e3f..27eb8afc9 100644
--- a/makefile_conf/chain/pirl.mk
+++ b/makefile_conf/chain/pirl.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/164'"
+PATH_APP_LOAD_PARAMS += "44'/164'"
 TICKER = "PIRL"
 CHAIN_ID = 3125659152
 APPNAME = "Pirl"
diff --git a/makefile_conf/chain/poa.mk b/makefile_conf/chain/poa.mk
index dd9f32e93..5590fc9d9 100644
--- a/makefile_conf/chain/poa.mk
+++ b/makefile_conf/chain/poa.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "POA"
 CHAIN_ID = 99
 APPNAME = "POA"
diff --git a/makefile_conf/chain/polygon.mk b/makefile_conf/chain/polygon.mk
index 0348401ee..71b8a03ff 100644
--- a/makefile_conf/chain/polygon.mk
+++ b/makefile_conf/chain/polygon.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "MATIC"
 CHAIN_ID = 137
 APPNAME = "Polygon"
diff --git a/makefile_conf/chain/reosc.mk b/makefile_conf/chain/reosc.mk
index 662e8a282..c90a3e034 100644
--- a/makefile_conf/chain/reosc.mk
+++ b/makefile_conf/chain/reosc.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/2894'"
+PATH_APP_LOAD_PARAMS += "44'/2894'"
 TICKER = "REOSC"
 CHAIN_ID = 2894
 APPNAME = "REOSC"
diff --git a/makefile_conf/chain/ropsten.mk b/makefile_conf/chain/ropsten.mk
deleted file mode 100644
index d709186f8..000000000
--- a/makefile_conf/chain/ropsten.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-APP_LOAD_PARAMS += --path "44'/60'"
-TICKER = "ETH"
-CHAIN_ID = 3
-# Allow to derive ETH 2 public keys
-APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1
-DEFINES += HAVE_ETH2
-APPNAME = "Eth Ropsten"
-DEFINES_LIB=
-DEFINES += HAVE_BOLOS_APP_STACK_CANARY
-APP_LOAD_FLAGS=--appFlags 0xa40
diff --git a/makefile_conf/chain/rsk.mk b/makefile_conf/chain/rsk.mk
index bdbef873a..0f056916d 100644
--- a/makefile_conf/chain/rsk.mk
+++ b/makefile_conf/chain/rsk.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/137'" --path "44'/00'"
+PATH_APP_LOAD_PARAMS += "44'/137'" "44'/00'"
 TICKER = "RBTC"
 CHAIN_ID = 30
 APPNAME = "RSK"
diff --git a/makefile_conf/chain/shiden.mk b/makefile_conf/chain/shiden.mk
index bda1c9d74..74bf66abd 100644
--- a/makefile_conf/chain/shiden.mk
+++ b/makefile_conf/chain/shiden.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/809'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/809'" "44'/60'"
 TICKER = "SDN"
 CHAIN_ID = 336
 APPNAME = "Shiden EVM"
diff --git a/makefile_conf/chain/shyft.mk b/makefile_conf/chain/shyft.mk
index 71ead2b20..ae9899470 100644
--- a/makefile_conf/chain/shyft.mk
+++ b/makefile_conf/chain/shyft.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/60'"
 TICKER = "SHFT"
 CHAIN_ID = 7341
 APPNAME = "Shyft"
diff --git a/makefile_conf/chain/songbird.mk b/makefile_conf/chain/songbird.mk
index 4c767ee0f..7dc4b6f5f 100644
--- a/makefile_conf/chain/songbird.mk
+++ b/makefile_conf/chain/songbird.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/554'" "44'/60'"
 TICKER = "SGB"
 CHAIN_ID = 19
 APPNAME = "Songbird"
diff --git a/makefile_conf/chain/tecracoin.mk b/makefile_conf/chain/tecracoin.mk
index 87a94ffdb..fc34beb0c 100644
--- a/makefile_conf/chain/tecracoin.mk
+++ b/makefile_conf/chain/tecracoin.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/554'"  --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/554'" "44'/60'"
 TICKER = "TCR"
 CHAIN_ID = 20531812
 APPNAME = "TecraCoin"
diff --git a/makefile_conf/chain/thundercore.mk b/makefile_conf/chain/thundercore.mk
index ea63c1af5..f602f3e7a 100644
--- a/makefile_conf/chain/thundercore.mk
+++ b/makefile_conf/chain/thundercore.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/1001'"
+PATH_APP_LOAD_PARAMS += "44'/1001'"
 TICKER = "TT"
 CHAIN_ID = 108
 APPNAME = "ThunderCore"
diff --git a/makefile_conf/chain/tomochain.mk b/makefile_conf/chain/tomochain.mk
index 19e2f4be0..24c7f553f 100644
--- a/makefile_conf/chain/tomochain.mk
+++ b/makefile_conf/chain/tomochain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/889'"
+PATH_APP_LOAD_PARAMS += "44'/889'"
 TICKER = "TOMO"
 CHAIN_ID = 88
 APPNAME = "TomoChain"
diff --git a/makefile_conf/chain/ubiq.mk b/makefile_conf/chain/ubiq.mk
index 840d30401..0796ea7dc 100644
--- a/makefile_conf/chain/ubiq.mk
+++ b/makefile_conf/chain/ubiq.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/108'"
+PATH_APP_LOAD_PARAMS += "44'/108'"
 TICKER = "UBQ"
 CHAIN_ID = 8
 APPNAME = "Ubiq"
diff --git a/makefile_conf/chain/volta.mk b/makefile_conf/chain/volta.mk
index 9230cbc30..1d3f51a59 100644
--- a/makefile_conf/chain/volta.mk
+++ b/makefile_conf/chain/volta.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/73799'" --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/73799'" "44'/60'"
 TICKER = "VOLTA"
 CHAIN_ID = 73799
 APPNAME = "Volta"
diff --git a/makefile_conf/chain/wanchain.mk b/makefile_conf/chain/wanchain.mk
index 66b6d82da..3453baa4e 100644
--- a/makefile_conf/chain/wanchain.mk
+++ b/makefile_conf/chain/wanchain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/5718350'"
+PATH_APP_LOAD_PARAMS += "44'/5718350'"
 TICKER = "WAN"
 CHAIN_ID = 888
 APPNAME = "Wanchain"
diff --git a/makefile_conf/chain/webchain.mk b/makefile_conf/chain/webchain.mk
index f2bb36496..c73fc644c 100644
--- a/makefile_conf/chain/webchain.mk
+++ b/makefile_conf/chain/webchain.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/227'"
+PATH_APP_LOAD_PARAMS += "44'/227'"
 TICKER = "WEB"
 CHAIN_ID = 24484
 APPNAME = "Webchain"
diff --git a/makefile_conf/chain/wethio.mk b/makefile_conf/chain/wethio.mk
index 11b29d70a..1b6f210fd 100644
--- a/makefile_conf/chain/wethio.mk
+++ b/makefile_conf/chain/wethio.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/77777'"
+PATH_APP_LOAD_PARAMS += "44'/77777'"
 TICKER = "ZYN"
 CHAIN_ID = 78
 APPNAME = "Wethio"
diff --git a/makefile_conf/chain/xdcnetwork.mk b/makefile_conf/chain/xdcnetwork.mk
index 9118483ac..9a553969c 100644
--- a/makefile_conf/chain/xdcnetwork.mk
+++ b/makefile_conf/chain/xdcnetwork.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/60'" --path "44'/550'"
+PATH_APP_LOAD_PARAMS += "44'/60'" "44'/550'"
 TICKER = "XDC"
 CHAIN_ID = 50
 APPNAME = "XDC Network"
diff --git a/makefile_conf/features.mk b/makefile_conf/features.mk
new file mode 100644
index 000000000..fa3c5d3c0
--- /dev/null
+++ b/makefile_conf/features.mk
@@ -0,0 +1,85 @@
+# Activate requested features
+# ---------------------------
+# Enables direct data signing without having to specify it in the settings. Useful when testing with speculos.
+ALLOW_DATA ?= 0
+ifneq ($(ALLOW_DATA),0)
+    DEFINES += HAVE_ALLOW_DATA
+endif
+
+# Bypass the signature verification for setExternalPlugin, setPlugin, provideERC20TokenInfo and provideNFTInfo calls
+BYPASS_SIGNATURES ?= 0
+ifneq ($(BYPASS_SIGNATURES),0)
+    DEFINES += HAVE_BYPASS_SIGNATURES
+endif
+
+# Enable the SET_PLUGIN test key
+SET_PLUGIN_TEST_KEY ?= 0
+ifneq ($(SET_PLUGIN_TEST_KEY),0)
+    DEFINES += HAVE_SET_PLUGIN_TEST_KEY
+endif
+
+# NFTs
+ifneq ($(TARGET_NAME),TARGET_NANOS)
+    DEFINES	+= HAVE_NFT_SUPPORT
+    NFT_TEST_KEY ?= 0
+    ifneq ($(NFT_TEST_KEY),0)
+        DEFINES += HAVE_NFT_TEST_KEY
+    endif
+    NFT_STAGING_KEY ?= 0
+    ifneq ($(NFT_STAGING_KEY),0)
+        # Key used by the staging backend
+        DEFINES += HAVE_NFT_STAGING_KEY
+    endif
+endif
+
+# Dynamic memory allocator
+ifneq ($(TARGET_NAME),TARGET_NANOS)
+    DEFINES += HAVE_DYN_MEM_ALLOC
+endif
+
+# EIP-712
+ifneq ($(TARGET_NAME),TARGET_NANOS)
+    DEFINES	+= HAVE_EIP712_FULL_SUPPORT
+endif
+
+# CryptoAssetsList key
+CAL_TEST_KEY ?= 0
+ifneq ($(CAL_TEST_KEY),0)
+    # Key used in our test framework
+    DEFINES += HAVE_CAL_TEST_KEY
+endif
+CAL_STAGING_KEY ?= 0
+ifneq ($(CAL_STAGING_KEY),0)
+    # Key used by the staging CAL
+    DEFINES += HAVE_CAL_STAGING_KEY
+endif
+
+# ENS
+ifneq ($(TARGET_NAME),TARGET_NANOS)
+    DEFINES += HAVE_DOMAIN_NAME
+    DOMAIN_NAME_TEST_KEY ?= 0
+    ifneq ($(DOMAIN_NAME_TEST_KEY),0)
+        DEFINES += HAVE_DOMAIN_NAME_TEST_KEY
+    endif
+endif
+
+ifneq ($(NOCONSENT),)
+    DEFINES += NO_CONSENT
+endif
+
+# Check features incompatibilities
+# --------------------------------
+# NFTs
+ifneq (,$(filter $(DEFINES),HAVE_NFT_TEST_KEY))
+    ifneq (, $(filter $(DEFINES),HAVE_NFT_STAGING_KEY))
+        $(error Multiple alternative NFT keys set at once)
+    endif
+endif
+
+# CryptoAssetsList key
+ifneq (,$(filter $(DEFINES),HAVE_CAL_TEST_KEY))
+    ifneq (, $(filter $(DEFINES),HAVE_CAL_STAGING_KEY))
+        # Can't use both the staging and testing keys
+        $(error Multiple alternative CAL keys set at once)
+    endif
+endif
diff --git a/src/eth_plugin_handler.c b/src/eth_plugin_handler.c
index c768c7e43..ddeeabcf3 100644
--- a/src/eth_plugin_handler.c
+++ b/src/eth_plugin_handler.c
@@ -102,11 +102,11 @@ static void eth_plugin_perform_init_default(uint8_t *contractAddress,
 static bool eth_plugin_perform_init_old_internal(uint8_t *contractAddress,
                                                  ethPluginInitContract_t *init) {
     uint8_t i, j;
-    const uint8_t **selectors;
+    const uint8_t *const *selectors;
 
     // Search internal plugin list
     for (i = 0;; i++) {
-        selectors = (const uint8_t **) PIC(INTERNAL_ETH_PLUGINS[i].selectors);
+        selectors = (const uint8_t *const *) PIC(INTERNAL_ETH_PLUGINS[i].selectors);
         if (selectors == NULL) {
             break;
         }
diff --git a/src/eth_plugin_internal.c b/src/eth_plugin_internal.c
index 2cfe351eb..12ed6cfd2 100644
--- a/src/eth_plugin_internal.c
+++ b/src/eth_plugin_internal.c
@@ -25,11 +25,11 @@ const uint8_t* const ETH2_SELECTORS[NUM_ETH2_SELECTORS] = {ETH2_DEPOSIT_SELECTOR
 // All internal alias names start with 'minus'
 
 const internalEthPlugin_t INTERNAL_ETH_PLUGINS[] = {
-    {NULL, (const uint8_t**) ERC20_SELECTORS, NUM_ERC20_SELECTORS, "-erc20", erc20_plugin_call},
+    {NULL, ERC20_SELECTORS, NUM_ERC20_SELECTORS, "-erc20", erc20_plugin_call},
 
 #ifdef HAVE_ETH2
 
-    {NULL, (const uint8_t**) ETH2_SELECTORS, NUM_ETH2_SELECTORS, "-eth2", eth2_plugin_call},
+    {NULL, ETH2_SELECTORS, NUM_ETH2_SELECTORS, "-eth2", eth2_plugin_call},
 
 #endif
 
diff --git a/src/eth_plugin_internal.h b/src/eth_plugin_internal.h
index ea84e407d..14eecea58 100644
--- a/src/eth_plugin_internal.h
+++ b/src/eth_plugin_internal.h
@@ -8,12 +8,12 @@
 void erc721_plugin_call(int message, void* parameters);
 void erc1155_plugin_call(int message, void* parameters);
 
-typedef bool (*PluginAvailableCheck)(void);
+typedef bool (*const PluginAvailableCheck)(void);
 typedef void (*PluginCall)(int, void*);
 
 typedef struct internalEthPlugin_t {
     PluginAvailableCheck availableCheck;
-    const uint8_t** selectors;
+    const uint8_t* const* selectors;
     uint8_t num_selectors;
     char alias[10];
     PluginCall impl;
diff --git a/src/handle_check_address.c b/src/handle_check_address.c
index fd0d79eab..e41bb7329 100644
--- a/src/handle_check_address.c
+++ b/src/handle_check_address.c
@@ -3,11 +3,11 @@
 #include "os.h"
 #include "shared_context.h"
 #include "string.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 
 #define ZERO(x) explicit_bzero(&x, sizeof(x))
 
-void handle_check_address(check_address_parameters_t* params, chain_config_t* chain_config) {
+void handle_check_address(check_address_parameters_t* params, const chain_config_t* chain_config) {
     params->result = 0;
     PRINTF("Params on the address %d\n", (unsigned int) params);
     PRINTF("Address to check %s\n", params->address_to_check);
diff --git a/src/handle_check_address.h b/src/handle_check_address.h
index 92db829c5..89a554136 100644
--- a/src/handle_check_address.h
+++ b/src/handle_check_address.h
@@ -5,6 +5,6 @@
 #include "chainConfig.h"
 
 void handle_check_address(check_address_parameters_t* check_address_params,
-                          chain_config_t* chain_config);
+                          const chain_config_t* chain_config);
 
 #endif  // _HANDLE_CHECK_ADDRESS_H_
diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c
index 22b3ac1d3..558650f0d 100644
--- a/src/handle_swap_sign_transaction.c
+++ b/src/handle_swap_sign_transaction.c
@@ -14,7 +14,7 @@
 static uint8_t* G_swap_sign_return_value_address;
 
 bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params,
-                                 chain_config_t* config) {
+                                 const chain_config_t* config) {
     // first copy parameters to stack, and then to global data.
     // We need this "trick" as the input data position can overlap with app-ethereum globals
     txStringProperties_t stack_data;
@@ -80,7 +80,7 @@ void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_succes
     os_lib_end();
 }
 
-void __attribute__((noreturn)) handle_swap_sign_transaction(chain_config_t* config) {
+void __attribute__((noreturn)) handle_swap_sign_transaction(const chain_config_t* config) {
 #ifdef HAVE_NBGL
     // On Stax, display a spinner at startup
     UX_INIT();
diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h
index 2c20f1eb5..1b5d877f2 100644
--- a/src/handle_swap_sign_transaction.h
+++ b/src/handle_swap_sign_transaction.h
@@ -4,8 +4,8 @@
 #include "chainConfig.h"
 
 bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params,
-                                 chain_config_t* config);
+                                 const chain_config_t* config);
 
-void __attribute__((noreturn)) handle_swap_sign_transaction(chain_config_t* config);
+void __attribute__((noreturn)) handle_swap_sign_transaction(const chain_config_t* config);
 
 void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success);
diff --git a/src/main.c b/src/main.c
index c148a7acc..74e661078 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,7 +31,7 @@
 #include "commands_712.h"
 #include "challenge.h"
 #include "domain_name.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 
 unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];
 
@@ -67,7 +67,7 @@ const internalStorage_t N_storage_real;
 #ifdef HAVE_NBGL
 caller_app_t *caller_app = NULL;
 #endif
-chain_config_t *chainConfig = NULL;
+const chain_config_t *chainConfig;
 
 void reset_app_context() {
     // PRINTF("!!RESET_APP_CONTEXT\n");
@@ -114,7 +114,7 @@ unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) {
     return 0;
 }
 
-extraInfo_t *getKnownToken(uint8_t *contractAddress) {
+extraInfo_t *getKnownToken(const uint8_t *contractAddress) {
     union extraInfo_t *currentItem = NULL;
     // Works for ERC-20 & NFT tokens since both structs in the union have the
     // contract address aligned
@@ -456,7 +456,7 @@ void app_main(void) {
 // override point, but nothing more to do
 #ifdef HAVE_BAGL
 void io_seproxyhal_display(const bagl_element_t *element) {
-    io_seproxyhal_display_default((bagl_element_t *) element);
+    io_seproxyhal_display_default(element);
 }
 #endif
 
@@ -526,7 +526,7 @@ void init_coin_config(chain_config_t *coin_config) {
     coin_config->chainId = CHAIN_ID;
 }
 
-void coin_main(libargs_t *args) {
+__attribute__((noreturn)) void coin_main(libargs_t *args) {
     chain_config_t config;
     if (args) {
         if (args->chain_config != NULL) {
@@ -612,10 +612,10 @@ void coin_main(libargs_t *args) {
         }
         END_TRY;
     }
-    app_exit();
+    os_sched_exit(-1);
 }
 
-void library_main(libargs_t *args) {
+__attribute__((noreturn)) void library_main(libargs_t *args) {
     chain_config_t coin_config;
     if (args->chain_config == NULL) {
         // We have been started directly by Exchange, not by a Clone. Init default chain
diff --git a/src/shared_context.h b/src/shared_context.h
index 4c1591404..51097081c 100644
--- a/src/shared_context.h
+++ b/src/shared_context.h
@@ -147,7 +147,7 @@ typedef union {
     strDataTmp_t tmp;
 } strings_t;
 
-extern chain_config_t *chainConfig;
+extern const chain_config_t *chainConfig;
 
 extern tmpCtx_t tmpCtx;
 extern txContext_t txContext;
diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h
index da704783a..0513c8694 100644
--- a/src/ui_callbacks.h
+++ b/src/ui_callbacks.h
@@ -26,6 +26,6 @@ void ui_warning_contract_data(void);
 
 void io_seproxyhal_send_status(uint32_t sw);
 void finalizeParsing(bool direct);
-extraInfo_t *getKnownToken(uint8_t *contractAddress);
+extraInfo_t *getKnownToken(const uint8_t *contractAddress);
 
 #endif  // _UI_CALLBACKS_H_
diff --git a/src/uint128.c b/src/uint128.c
index b720e35c1..1dda65046 100644
--- a/src/uint128.c
+++ b/src/uint128.c
@@ -53,11 +53,9 @@ void shiftl128(const uint128_t *const number, uint32_t value, uint128_t *const t
     } else if (value < 64) {
         UPPER_P(target) = (UPPER_P(number) << value) + (LOWER_P(number) >> (64 - value));
         LOWER_P(target) = (LOWER_P(number) << value);
-    } else if ((128 > value) && (value > 64)) {
+    } else {
         UPPER_P(target) = LOWER_P(number) << (value - 64);
         LOWER_P(target) = 0;
-    } else {
-        clear128(target);
     }
 }
 
@@ -74,11 +72,9 @@ void shiftr128(const uint128_t *const number, uint32_t value, uint128_t *const t
         UPPER(result) = UPPER_P(number) >> value;
         LOWER(result) = (UPPER_P(number) << (64 - value)) + (LOWER_P(number) >> value);
         copy128(target, &result);
-    } else if ((128 > value) && (value > 64)) {
+    } else {
         LOWER_P(target) = UPPER_P(number) >> (value - 64);
         UPPER_P(target) = 0;
-    } else {
-        clear128(target);
     }
 }
 
diff --git a/src/uint256.c b/src/uint256.c
index fb6d236c6..7445b426c 100644
--- a/src/uint256.c
+++ b/src/uint256.c
@@ -59,11 +59,9 @@ void shiftl256(const uint256_t *const number, uint32_t value, uint256_t *const t
         add128(&tmp1, &tmp2, &UPPER(result));
         shiftl128(&LOWER_P(number), value, &LOWER(result));
         copy256(target, &result);
-    } else if ((256 > value) && (value > 128)) {
+    } else {
         shiftl128(&LOWER_P(number), (value - 128), &UPPER_P(target));
         clear128(&LOWER_P(target));
-    } else {
-        clear256(target);
     }
 }
 
@@ -84,11 +82,9 @@ void shiftr256(const uint256_t *const number, uint32_t value, uint256_t *const t
         shiftl128(&UPPER_P(number), (128 - value), &tmp2);
         add128(&tmp1, &tmp2, &LOWER(result));
         copy256(target, &result);
-    } else if ((256 > value) && (value > 128)) {
+    } else {
         shiftr128(&UPPER_P(number), (value - 128), &LOWER_P(target));
         clear128(&UPPER_P(target));
-    } else {
-        clear256(target);
     }
 }
 
diff --git a/src/uint_common.c b/src/uint_common.c
index 5fe06a7c4..bdb51f44d 100644
--- a/src/uint_common.c
+++ b/src/uint_common.c
@@ -58,3 +58,20 @@ void reverseString(char *const str, uint32_t length) {
         str[j] = c;
     }
 }
+
+int bytes_to_string(char *out, size_t outl, const void *value, size_t len) {
+    if (outl <= 2) {
+        // Need at least '0x' and 1 digit
+        return -1;
+    }
+    if (strlcpy(out, "0x", outl) != 2) {
+        goto err;
+    }
+    if (format_hex(value, len, out + 2, outl - 2) < 0) {
+        goto err;
+    }
+    return 0;
+err:
+    *out = '\0';
+    return -1;
+}
diff --git a/src/uint_common.h b/src/uint_common.h
index c12d9e89f..59c726ad8 100644
--- a/src/uint_common.h
+++ b/src/uint_common.h
@@ -21,6 +21,9 @@
 #define _UINT_COMMON_H_
 
 #include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "format.h"
 
 #define UPPER_P(x) x->elements[0]
 #define LOWER_P(x) x->elements[1]
@@ -32,4 +35,6 @@ void read_u64_be(const uint8_t *const in, uint64_t *const out);
 uint64_t readUint64BE(const uint8_t *const buffer);
 void reverseString(char *const str, uint32_t length);
 
+int bytes_to_string(char *out, size_t outl, const void *value, size_t len);
+
 #endif  //_UINT_COMMON_H_
diff --git a/src_bagl/ui_flow_getEth2PublicKey.c b/src_bagl/ui_flow_getEth2PublicKey.c
index af2142f94..2eedfa00f 100644
--- a/src_bagl/ui_flow_getEth2PublicKey.c
+++ b/src_bagl/ui_flow_getEth2PublicKey.c
@@ -2,9 +2,13 @@
 
 #include "shared_context.h"
 #include "ui_callbacks.h"
+#include "uint_common.h"
 
 void prepare_eth2_public_key() {
-    snprintf(strings.tmp.tmp, 100, "0x%.*H", 48, tmpCtx.publicKeyContext.publicKey.W);
+    bytes_to_string(strings.tmp.tmp,
+                    sizeof(strings.tmp.tmp),
+                    tmpCtx.publicKeyContext.publicKey.W,
+                    48);
 }
 
 // clang-format off
diff --git a/src_bagl/ui_flow_signMessage712.c b/src_bagl/ui_flow_signMessage712.c
index d21d04749..1bd767a93 100644
--- a/src_bagl/ui_flow_signMessage712.c
+++ b/src_bagl/ui_flow_signMessage712.c
@@ -57,7 +57,7 @@ UX_STEP_INIT(
 UX_STEP_CB(
     ux_712_step_approve,
     pb,
-    ui_712_approve(NULL),
+    ui_712_approve(),
     {
       &C_icon_validate_14,
       "Approve",
@@ -65,7 +65,7 @@ UX_STEP_CB(
 UX_STEP_CB(
     ux_712_step_reject,
     pb,
-    ui_712_reject(NULL),
+    ui_712_reject(),
     {
       &C_icon_crossmark,
       "Reject",
diff --git a/src_bagl/ui_flow_signMessage712_v0.c b/src_bagl/ui_flow_signMessage712_v0.c
index 9cdda7051..6eb88b657 100644
--- a/src_bagl/ui_flow_signMessage712_v0.c
+++ b/src_bagl/ui_flow_signMessage712_v0.c
@@ -1,21 +1,20 @@
 #include "shared_context.h"
 #include "ui_callbacks.h"
 #include "common_712.h"
+#include "uint_common.h"
 
 void prepare_domain_hash_v0() {
-    snprintf(strings.tmp.tmp,
-             sizeof(strings.tmp.tmp),
-             "0x%.*H",
-             KECCAK256_HASH_BYTESIZE,
-             tmpCtx.messageSigningContext712.domainHash);
+    bytes_to_string(strings.tmp.tmp,
+                    sizeof(strings.tmp.tmp),
+                    tmpCtx.messageSigningContext712.domainHash,
+                    KECCAK256_HASH_BYTESIZE);
 }
 
 void prepare_message_hash_v0() {
-    snprintf(strings.tmp.tmp,
-             sizeof(strings.tmp.tmp),
-             "0x%.*H",
-             KECCAK256_HASH_BYTESIZE,
-             tmpCtx.messageSigningContext712.messageHash);
+    bytes_to_string(strings.tmp.tmp,
+                    sizeof(strings.tmp.tmp),
+                    tmpCtx.messageSigningContext712.messageHash,
+                    KECCAK256_HASH_BYTESIZE);
 }
 
 // clang-format off
@@ -46,7 +45,7 @@ UX_STEP_NOCB_INIT(
 UX_STEP_CB(
     ux_sign_712_v0_flow_4_step,
     pbb,
-    ui_712_approve_cb(NULL),
+    ui_712_approve_cb(),
     {
       &C_icon_validate_14,
       "Sign",
@@ -55,7 +54,7 @@ UX_STEP_CB(
 UX_STEP_CB(
     ux_sign_712_v0_flow_5_step,
     pbb,
-    ui_712_reject_cb(NULL),
+    ui_712_reject_cb(),
     {
       &C_icon_crossmark,
       "Cancel",
diff --git a/src_common/asset_info.h b/src_common/asset_info.h
deleted file mode 100644
index a2ce39332..000000000
--- a/src_common/asset_info.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#pragma once
-
-#include <stdint.h>
-#include "common_utils.h"
-
-// NFT
-
-#define COLLECTION_NAME_MAX_LEN 70
-
-typedef struct nftInfo_t {
-    uint8_t contractAddress[ADDRESS_LENGTH];  // must be first item
-    char collectionName[COLLECTION_NAME_MAX_LEN + 1];
-} nftInfo_t;
-
-// TOKENS
-
-#define MAX_TICKER_LEN 11  // 10 characters + '\0'
-#define MAX_ITEMS      2
-
-typedef struct tokenDefinition_t {
-    uint8_t address[ADDRESS_LENGTH];  // must be first item
-#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
-    uint8_t contractName[ADDRESS_LENGTH];
-#endif
-    char ticker[MAX_TICKER_LEN];
-    uint8_t decimals;
-} tokenDefinition_t;
-
-// UNION
-
-typedef union extraInfo_t {
-    tokenDefinition_t token;
-    nftInfo_t nft;
-} extraInfo_t;
diff --git a/src_common/caller_api.h b/src_common/caller_api.h
deleted file mode 100644
index 7f769bee9..000000000
--- a/src_common/caller_api.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#pragma once
-
-#ifdef HAVE_NBGL
-#include "ux.h"
-#endif
-
-typedef enum { CALLER_TYPE_CLONE, CALLER_TYPE_PLUGIN } e_caller_type;
-
-typedef struct caller_app_t {
-    const char *name;
-#ifdef HAVE_NBGL
-    const nbgl_icon_details_t *icon;
-#endif
-    char type;  // does not have to be set by the caller app
-} caller_app_t;
-
-extern caller_app_t *caller_app;
diff --git a/src_common/common_utils.c b/src_common/common_utils.c
deleted file mode 100644
index 44d31ba61..000000000
--- a/src_common/common_utils.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#include <stdint.h>
-#include <string.h>
-
-#include "asset_info.h"
-#include "common_utils.h"
-#include "lcx_ecfp.h"
-#include "lcx_sha3.h"
-
-void array_hexstr(char *strbuf, const void *bin, unsigned int len) {
-    while (len--) {
-        *strbuf++ = HEXDIGITS[((*((char *) bin)) >> 4) & 0xF];
-        *strbuf++ = HEXDIGITS[(*((char *) bin)) & 0xF];
-        bin = (const void *) ((unsigned int) bin + 1);
-    }
-    *strbuf = 0;  // EOS
-}
-
-uint64_t u64_from_BE(const uint8_t *in, uint8_t size) {
-    uint8_t i = 0;
-    uint64_t res = 0;
-
-    while (i < size && i < sizeof(res)) {
-        res <<= 8;
-        res |= in[i];
-        i++;
-    }
-
-    return res;
-}
-
-bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size) {
-    // Copy the numbers in ASCII format.
-    uint8_t i = 0;
-    do {
-        // Checking `i + 1` to make sure we have enough space for '\0'.
-        if (i + 1 >= dst_size) {
-            return false;
-        }
-        dst[i] = src % 10 + '0';
-        src /= 10;
-        i++;
-    } while (src);
-
-    // Null terminate string
-    dst[i] = '\0';
-
-    // Revert the string
-    i--;
-    uint8_t j = 0;
-    while (j < i) {
-        char tmp = dst[i];
-        dst[i] = dst[j];
-        dst[j] = tmp;
-        i--;
-        j++;
-    }
-    return true;
-}
-
-bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) {
-    if (value_len > INT256_LENGTH) {
-        // value len is bigger than INT256_LENGTH ?!
-        return false;
-    }
-
-    uint16_t n[16] = {0};
-    // Copy and right-align the number
-    memcpy((uint8_t *) n + INT256_LENGTH - value_len, value, value_len);
-
-    // Special case when value is 0
-    if (allzeroes(n, INT256_LENGTH)) {
-        if (out_len < 2) {
-            // Not enough space to hold "0" and \0.
-            return false;
-        }
-        strlcpy(out, "0", out_len);
-        return true;
-    }
-
-    uint16_t *p = n;
-    for (int i = 0; i < 16; i++) {
-        n[i] = __builtin_bswap16(*p++);
-    }
-    int pos = out_len;
-    while (!allzeroes(n, sizeof(n))) {
-        if (pos == 0) {
-            return false;
-        }
-        pos -= 1;
-        unsigned int carry = 0;
-        for (int i = 0; i < 16; i++) {
-            int rem = ((carry << 16) | n[i]) % 10;
-            n[i] = ((carry << 16) | n[i]) / 10;
-            carry = rem;
-        }
-        out[pos] = '0' + carry;
-    }
-    memmove(out, out + pos, out_len - pos);
-    out[out_len - pos] = 0;
-    return true;
-}
-
-bool adjustDecimals(const char *src,
-                    size_t srcLength,
-                    char *target,
-                    size_t targetLength,
-                    uint8_t decimals) {
-    uint32_t startOffset;
-    uint32_t lastZeroOffset = 0;
-    uint32_t offset = 0;
-    if ((srcLength == 1) && (*src == '0')) {
-        if (targetLength < 2) {
-            return false;
-        }
-        target[0] = '0';
-        target[1] = '\0';
-        return true;
-    }
-    if (srcLength <= decimals) {
-        uint32_t delta = decimals - srcLength;
-        if (targetLength < srcLength + 1 + 2 + delta) {
-            return false;
-        }
-        target[offset++] = '0';
-        target[offset++] = '.';
-        for (uint32_t i = 0; i < delta; i++) {
-            target[offset++] = '0';
-        }
-        startOffset = offset;
-        for (uint32_t i = 0; i < srcLength; i++) {
-            target[offset++] = src[i];
-        }
-        target[offset] = '\0';
-    } else {
-        uint32_t sourceOffset = 0;
-        uint32_t delta = srcLength - decimals;
-        if (targetLength < srcLength + 1 + 1) {
-            return false;
-        }
-        while (offset < delta) {
-            target[offset++] = src[sourceOffset++];
-        }
-        if (decimals != 0) {
-            target[offset++] = '.';
-        }
-        startOffset = offset;
-        while (sourceOffset < srcLength) {
-            target[offset++] = src[sourceOffset++];
-        }
-        target[offset] = '\0';
-    }
-    for (uint32_t i = startOffset; i < offset; i++) {
-        if (target[i] == '0') {
-            if (lastZeroOffset == 0) {
-                lastZeroOffset = i;
-            }
-        } else {
-            lastZeroOffset = 0;
-        }
-    }
-    if (lastZeroOffset != 0) {
-        target[lastZeroOffset] = '\0';
-        if (target[lastZeroOffset - 1] == '.') {
-            target[lastZeroOffset - 1] = '\0';
-        }
-    }
-    return true;
-}
-
-bool amountToString(const uint8_t *amount,
-                    uint8_t amount_size,
-                    uint8_t decimals,
-                    const char *ticker,
-                    char *out_buffer,
-                    size_t out_buffer_size) {
-    char tmp_buffer[100] = {0};
-
-    if (uint256_to_decimal(amount, amount_size, tmp_buffer, sizeof(tmp_buffer)) == false) {
-        return false;
-    }
-
-    uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer));
-    uint8_t ticker_len = strnlen(ticker, MAX_TICKER_LEN);
-
-    if (ticker_len > 0) {
-        if (out_buffer_size <= ticker_len + 1) {
-            return false;
-        }
-        memcpy(out_buffer, ticker, ticker_len);
-        out_buffer[ticker_len++] = ' ';
-    }
-
-    if (adjustDecimals(tmp_buffer,
-                       amount_len,
-                       out_buffer + ticker_len,
-                       out_buffer_size - ticker_len - 1,
-                       decimals) == false) {
-        return false;
-    }
-
-    out_buffer[out_buffer_size - 1] = '\0';
-    return true;
-}
-
-void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65],
-                             uint8_t out[static ADDRESS_LENGTH]) {
-    uint8_t hashAddress[CX_KECCAK_256_SIZE];
-    CX_ASSERT(cx_keccak_256_hash(raw_pubkey + 1, 64, hashAddress));
-    memmove(out, hashAddress + 12, ADDRESS_LENGTH);
-}
-
-void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65],
-                                   char out[static ADDRESS_LENGTH * 2],
-                                   uint64_t chainId) {
-    uint8_t hashAddress[CX_KECCAK_256_SIZE];
-    CX_ASSERT(cx_keccak_256_hash(raw_pubkey + 1, 64, hashAddress));
-    getEthAddressStringFromBinary(hashAddress + 12, out, chainId);
-}
-
-bool getEthAddressStringFromBinary(uint8_t *address,
-                                   char out[static ADDRESS_LENGTH * 2],
-                                   uint64_t chainId) {
-    // save some precious stack space
-    union locals_union {
-        uint8_t hashChecksum[INT256_LENGTH];
-        uint8_t tmp[51];
-    } locals_union;
-
-    uint8_t i;
-    bool eip1191 = false;
-    uint32_t offset = 0;
-    switch (chainId) {
-        case 30:
-        case 31:
-            eip1191 = true;
-            break;
-    }
-    if (eip1191) {
-        if (!u64_to_string(chainId, (char *) locals_union.tmp, sizeof(locals_union.tmp))) {
-            return false;
-        }
-        offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
-        strlcat((char *) locals_union.tmp + offset, "0x", sizeof(locals_union.tmp) - offset);
-        offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
-    }
-    for (i = 0; i < 20; i++) {
-        uint8_t digit = address[i];
-        locals_union.tmp[offset + 2 * i] = HEXDIGITS[(digit >> 4) & 0x0f];
-        locals_union.tmp[offset + 2 * i + 1] = HEXDIGITS[digit & 0x0f];
-    }
-    if (cx_keccak_256_hash(locals_union.tmp, offset + 40, locals_union.hashChecksum) != CX_OK) {
-        return false;
-    }
-
-    for (i = 0; i < 40; i++) {
-        uint8_t digit = address[i / 2];
-        if ((i % 2) == 0) {
-            digit = (digit >> 4) & 0x0f;
-        } else {
-            digit = digit & 0x0f;
-        }
-        if (digit < 10) {
-            out[i] = HEXDIGITS[digit];
-        } else {
-            int v = (locals_union.hashChecksum[i / 2] >> (4 * (1 - i % 2))) & 0x0f;
-            if (v >= 8) {
-                out[i] = HEXDIGITS[digit] - 'a' + 'A';
-            } else {
-                out[i] = HEXDIGITS[digit];
-            }
-        }
-    }
-    out[40] = '\0';
-
-    return true;
-}
-
-/* Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary
-format by `in`. (eg: uint8_t*:0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB ->
-char*:"0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB\0" ).*/
-bool getEthDisplayableAddress(uint8_t *in, char *out, size_t out_len, uint64_t chainId) {
-    if (out_len < 43) {
-        strlcpy(out, "ERROR", out_len);
-        return false;
-    }
-    out[0] = '0';
-    out[1] = 'x';
-    if (!getEthAddressStringFromBinary(in, out + 2, chainId)) {
-        strlcpy(out, "ERROR", out_len);
-        return false;
-    }
-
-    return true;
-}
diff --git a/src_common/common_utils.h b/src_common/common_utils.h
deleted file mode 100644
index 2c1a8dd3d..000000000
--- a/src_common/common_utils.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "os.h"
-#include "cx.h"
-
-#define WEI_TO_ETHER 18
-
-#define ADDRESS_LENGTH 20
-#define INT128_LENGTH  16
-#define INT256_LENGTH  32
-
-#define KECCAK256_HASH_BYTESIZE 32
-
-static const char HEXDIGITS[] = "0123456789abcdef";
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
-void array_hexstr(char *strbuf, const void *bin, unsigned int len);
-
-uint64_t u64_from_BE(const uint8_t *in, uint8_t size);
-
-bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size);
-
-bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len);
-
-bool amountToString(const uint8_t *amount,
-                    uint8_t amount_len,
-                    uint8_t decimals,
-                    const char *ticker,
-                    char *out_buffer,
-                    size_t out_buffer_size);
-
-bool adjustDecimals(const char *src,
-                    size_t srcLength,
-                    char *target,
-                    size_t targetLength,
-                    uint8_t decimals);
-
-void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65],
-                             uint8_t out[static ADDRESS_LENGTH]);
-
-void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65],
-                                   char out[static ADDRESS_LENGTH * 2],
-                                   uint64_t chainId);
-
-bool getEthAddressStringFromBinary(uint8_t *address,
-                                   char out[static ADDRESS_LENGTH * 2],
-                                   uint64_t chainId);
-
-bool getEthDisplayableAddress(uint8_t *in, char *out, size_t out_len, uint64_t chainId);
-
-static __attribute__((no_instrument_function)) inline int allzeroes(const void *buf, size_t n) {
-    uint8_t *p = (uint8_t *) buf;
-    for (size_t i = 0; i < n; ++i) {
-        if (p[i]) {
-            return 0;
-        }
-    }
-    return 1;
-}
-static __attribute__((no_instrument_function)) inline int ismaxint(uint8_t *buf, int n) {
-    for (int i = 0; i < n; ++i) {
-        if (buf[i] != 0xff) {
-            return 0;
-        }
-    }
-    return 1;
-}
diff --git a/src_common/eth_plugin_interface.h b/src_common/eth_plugin_interface.h
deleted file mode 100644
index 6d872f5bc..000000000
--- a/src_common/eth_plugin_interface.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// clang-format off
-
-#pragma once
-
-#include "os.h"
-#include "cx.h"
-
-// Include other header compatible with plugins
-#include "asset_info.h"
-#include "caller_api.h"
-#include "common_utils.h"
-#include "plugin_utils.h"
-#include "tx_content.h"
-
-/*************************************************************************************************
- * Comments provided in this file are quick reminders on the usage of the plugin interface       *
- * Reading the real plugin documentation is GREATLY recommended.                                 *
- * You can find the latest version here:                                                         *
- * https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp_plugins.adoc                 *
- *************************************************************************************************/
-
-// Interface version. Will be updated every time a breaking change in the interface is introduced.
-typedef enum eth_plugin_interface_version_e {
-    ETH_PLUGIN_INTERFACE_VERSION_1 = 1,
-    ETH_PLUGIN_INTERFACE_VERSION_2 = 2,
-    ETH_PLUGIN_INTERFACE_VERSION_3 = 3,
-    ETH_PLUGIN_INTERFACE_VERSION_4 = 4,
-    ETH_PLUGIN_INTERFACE_VERSION_5 = 5,
-    ETH_PLUGIN_INTERFACE_VERSION_LATEST = 6,
-} eth_plugin_interface_version_t;
-
-
-// Codes for the different requests Ethereum can send to the plugin
-// The dispatch is handled by the SDK itself, the plugin code does not have to handle it
-typedef enum eth_plugin_msg_e {
-    // Codes for actions the Ethereum app can ask the plugin to perform
-    ETH_PLUGIN_INIT_CONTRACT = 0x0101,
-    ETH_PLUGIN_PROVIDE_PARAMETER = 0x0102,
-    ETH_PLUGIN_FINALIZE = 0x0103,
-    ETH_PLUGIN_PROVIDE_INFO = 0x0104,
-    ETH_PLUGIN_QUERY_CONTRACT_ID = 0x0105,
-    ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106,
-
-    // Special request: the Ethereum app is checking if we are installed on the device
-    ETH_PLUGIN_CHECK_PRESENCE = 0x01FF,
-} eth_plugin_msg_t;
-
-
-// Reply codes when responding to the Ethereum application
-typedef enum eth_plugin_result_e {
-    // Unsuccessful return values
-    ETH_PLUGIN_RESULT_ERROR = 0x00,
-    ETH_PLUGIN_RESULT_UNAVAILABLE = 0x01,
-    ETH_PLUGIN_RESULT_UNSUCCESSFUL = 0x02,  // Used for comparison
-
-    // Successful return values
-    ETH_PLUGIN_RESULT_SUCCESSFUL = 0x03,  // Used for comparison
-    ETH_PLUGIN_RESULT_OK = 0x04,
-    ETH_PLUGIN_RESULT_OK_ALIAS = 0x05,
-    ETH_PLUGIN_RESULT_FALLBACK = 0x06,
-} eth_plugin_result_t;
-
-
-// Format of UI the Ethereum application has to use for this plugin
-typedef enum eth_ui_type_e {
-    // If uiType is UI_AMOUNT_ADDRESS, Ethereum will use the amount/address UI
-    // the amount and address provided by the plugin will be used
-    // If tokenLookup1 is set, the amount is provided for this token
-    ETH_UI_TYPE_AMOUNT_ADDRESS = 0x01,
-
-    // If uiType is UI_TYPE_GENERIC, Ethereum will use the dedicated ETH plugin UI
-    // the ETH application provides tokens if requested then prompts for each UI field
-    // The first field is forced by the ETH app to be the name + version of the plugin handling the
-    // request. The last field is the fee amount
-    ETH_UI_TYPE_GENERIC = 0x02,
-} eth_ui_type_t;
-
-
-// Scratch objects and utilities available to the plugin READ-WRITE
-typedef struct ethPluginSharedRW_s {
-    cx_sha3_t *sha3;
-} ethPluginSharedRW_t;
-
-
-// Transaction data available to the plugin READ-ONLY
-typedef struct ethPluginSharedRO_s {
-    txContent_t *txContent;
-} ethPluginSharedRO_t;
-
-
-// Plugin-only memory allocated by the Ethereum application and used by the plugin.
-#define PLUGIN_CONTEXT_SIZE (5 * INT256_LENGTH)
-// It is recommended to cast the raw uin8_t array to a structure meaningful for your plugin
-// Helper to check that the actual plugin context structure is not bigger than the allocated memory
-#define ASSERT_SIZEOF_PLUGIN_CONTEXT(s) \
-    _Static_assert(sizeof(s) <= PLUGIN_CONTEXT_SIZE, "Plugin context structure is too big.")
-
-
-/*
- * HANDLERS AND PARAMETERS
- * Parameters associated with the requests the Ethereum application can ask the plugin to perform
- * The plugin SDK will automatically call the relevant handler for the received code, so the plugin
- * has to define each of the handler functions declared below.
- */
-
-
-// Init Contract
-
-typedef struct ethPluginInitContract_s {
-    eth_plugin_interface_version_t interfaceVersion;
-    eth_plugin_result_t result;
-
-    // in
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    uint8_t *pluginContext;
-    size_t pluginContextLength;
-    const uint8_t *selector;  // 4 bytes selector
-    size_t dataSize;
-
-    char *alias;  // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set
-
-} ethPluginInitContract_t;
-// void handle_init_contract(ethPluginInitContract_t *parameters);
-
-
-// Provide parameter
-
-typedef struct ethPluginProvideParameter_s {
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
-    const uint8_t *parameter;  // 32 bytes parameter
-    uint32_t parameterOffset;
-
-    eth_plugin_result_t result;
-
-} ethPluginProvideParameter_t;
-// void handle_provide_parameter(ethPluginProvideParameter_t *parameters);
-
-
-// Finalize
-
-typedef struct ethPluginFinalize_s {
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
-
-    uint8_t *tokenLookup1;  // set by the plugin if a token should be looked up
-    uint8_t *tokenLookup2;
-
-    const uint8_t *amount;   // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS
-    const uint8_t *address;  // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set
-                             // to the user's address if uiType is UI_TYPE_GENERIC
-
-    eth_ui_type_t uiType;
-    uint8_t numScreens;  // ignored if uiType is UI_AMOUNT_ADDRESS
-    eth_plugin_result_t result;
-
-} ethPluginFinalize_t;
-// void handle_finalize(ethPluginFinalize_t *parameters);
-
-
-// Provide token
-
-typedef struct ethPluginProvideInfo_s {
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
-
-    union extraInfo_t *item1;  // set by the ETH application, to be saved by the plugin
-    union extraInfo_t *item2;
-
-    uint8_t additionalScreens;  // Used by the plugin if it needs to display additional screens
-                                // based on the information received from the token definitions.
-
-    eth_plugin_result_t result;
-
-} ethPluginProvideInfo_t;
-// void handle_provide_token(ethPluginProvideInfo_t *parameters);
-
-
-// Query Contract name and version
-
-// This is always called on the non aliased contract
-
-typedef struct ethQueryContractID_s {
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
-
-    char *name;
-    size_t nameLength;
-    char *version;
-    size_t versionLength;
-
-    eth_plugin_result_t result;
-
-} ethQueryContractID_t;
-// void handle_query_contract_id(ethQueryContractID_t *parameters);
-
-
-// Query Contract UI
-
-typedef struct ethQueryContractUI_s {
-    ethPluginSharedRW_t *pluginSharedRW;
-    ethPluginSharedRO_t *pluginSharedRO;
-    union extraInfo_t *item1;
-    union extraInfo_t *item2;
-    char network_ticker[MAX_TICKER_LEN];
-    uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
-    uint8_t screenIndex;
-
-    char *title;
-    size_t titleLength;
-    char *msg;
-    size_t msgLength;
-
-    eth_plugin_result_t result;
-
-} ethQueryContractUI_t;
-// void handle_query_contract_ui(ethQueryContractUI_t *parameters);
-
-// clang-format on
diff --git a/src_common/plugin_utils.c b/src_common/plugin_utils.c
deleted file mode 100644
index 5216fdb0b..000000000
--- a/src_common/plugin_utils.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <string.h>
-
-#include "common_utils.h"
-#include "plugin_utils.h"
-
-void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) {
-    uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH);
-    memmove(dst, parameter + PARAMETER_LENGTH - copy_size, copy_size);
-}
-
-void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) {
-    uint8_t copy_size = MIN(dst_size, PARAMETER_LENGTH);
-    memmove(dst, parameter, copy_size);
-}
-
-bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value) {
-    if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint16_t))) {
-        *value = U2BE(parameter, PARAMETER_LENGTH - sizeof(uint16_t));
-        return true;
-    }
-
-    return false;
-}
-
-bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value) {
-    if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint32_t))) {
-        *value = U4BE(parameter, PARAMETER_LENGTH - sizeof(uint32_t));
-        return true;
-    }
-
-    return false;
-}
-
-bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx) {
-    for (size_t i = 0; i < size; ++i) {
-        if (selector == array[i]) {
-            if (idx != NULL) *idx = i;
-            return true;
-        }
-    }
-    return false;
-}
diff --git a/src_common/plugin_utils.h b/src_common/plugin_utils.h
deleted file mode 100644
index b37da7abc..000000000
--- a/src_common/plugin_utils.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*****************************************************************************
- *   Ledger
- *   (c) 2023 Ledger SAS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *****************************************************************************/
-
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "eth_plugin_interface.h"
-
-#define SELECTOR_SIZE    4
-#define PARAMETER_LENGTH 32
-
-void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size);
-
-void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size);
-
-// Get the value from the beginning of the parameter (right to left) and check if the rest of it is
-// zero
-bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value);
-bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value);
-
-bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx);
diff --git a/src_common/tx_content.h b/src_common/tx_content.h
deleted file mode 100644
index ffb0afcf8..000000000
--- a/src_common/tx_content.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#pragma once
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "os.h"
-#include "cx.h"
-#include "common_utils.h"
-
-typedef struct txInt256_t {
-    uint8_t value[INT256_LENGTH];
-    uint8_t length;
-} txInt256_t;
-
-typedef struct txContent_t {
-    txInt256_t gasprice;  // Used as MaxFeePerGas when dealing with EIP1559 transactions.
-    txInt256_t startgas;  // Also known as `gasLimit`.
-    txInt256_t value;
-    txInt256_t nonce;
-    txInt256_t chainID;
-    uint8_t destination[ADDRESS_LENGTH];
-    uint8_t destinationLength;
-    uint8_t v[8];
-    uint8_t vLength;
-    bool dataPresent;
-} txContent_t;
diff --git a/src_features/getAppConfiguration/cmd_getAppConfiguration.c b/src_features/getAppConfiguration/cmd_getAppConfiguration.c
index c882b115b..8b137d503 100644
--- a/src_features/getAppConfiguration/cmd_getAppConfiguration.c
+++ b/src_features/getAppConfiguration/cmd_getAppConfiguration.c
@@ -14,9 +14,9 @@ void handleGetAppConfiguration(uint8_t p1,
     UNUSED(flags);
     G_io_apdu_buffer[0] = (N_storage.dataAllowed ? APP_FLAG_DATA_ALLOWED : 0x00);
     G_io_apdu_buffer[0] |= APP_FLAG_EXTERNAL_TOKEN_NEEDED;
-    G_io_apdu_buffer[1] = LEDGER_MAJOR_VERSION;
-    G_io_apdu_buffer[2] = LEDGER_MINOR_VERSION;
-    G_io_apdu_buffer[3] = LEDGER_PATCH_VERSION;
+    G_io_apdu_buffer[1] = MAJOR_VERSION;
+    G_io_apdu_buffer[2] = MINOR_VERSION;
+    G_io_apdu_buffer[3] = PATCH_VERSION;
     *tx = 4;
     THROW(0x9000);
 }
diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c
index dbc84bb6b..4c5a11566 100644
--- a/src_features/getPublicKey/cmd_getPublicKey.c
+++ b/src_features/getPublicKey/cmd_getPublicKey.c
@@ -4,7 +4,7 @@
 #include "feature_getPublicKey.h"
 #include "common_ui.h"
 #include "os_io_seproxyhal.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 
 void handleGetPublicKey(uint8_t p1,
                         uint8_t p2,
diff --git a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
index c0120f0d0..a58ab1981 100644
--- a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
+++ b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c
@@ -3,6 +3,7 @@
 
 #include "feature_performPrivacyOperation.h"
 #include "common_ui.h"
+#include "uint_common.h"
 
 #define P2_PUBLIC_ENCRYPTION_KEY 0x00
 #define P2_SHARED_SECRET         0x01
@@ -106,11 +107,11 @@ void handlePerformPrivacyOperation(uint8_t p1,
         for (uint8_t i = 0; i < 32; i++) {
             privateKeyData[i] = tmpCtx.publicKeyContext.publicKey.W[32 - i];
         }
-        snprintf(strings.common.fullAmount,
-                 sizeof(strings.common.fullAmount) - 1,
-                 "%.*H",
-                 32,
-                 privateKeyData);
+        format_hex(privateKeyData,
+                   32,
+                   strings.common.fullAmount,
+                   sizeof(strings.common.fullAmount) - 1);
+
         if (p2 == P2_PUBLIC_ENCRYPTION_KEY) {
             ui_display_privacy_public_key();
         } else {
diff --git a/src_features/performPrivacyOperation/feature_performPrivacyOperation.h b/src_features/performPrivacyOperation/feature_performPrivacyOperation.h
index df80ffd54..1e519d386 100644
--- a/src_features/performPrivacyOperation/feature_performPrivacyOperation.h
+++ b/src_features/performPrivacyOperation/feature_performPrivacyOperation.h
@@ -1,3 +1,8 @@
+#ifndef _PERFORM_PRIVACY_OPERATION_H_
+#define _PERFORM_PRIVACY_OPERATION_H_
+
 #include "shared_context.h"
 
 uint32_t set_result_perform_privacy_operation(void);
+
+#endif  // _PERFORM_PRIVACY_OPERATION_H_
diff --git a/src_features/provideNFTInformation/cmd_provideNFTInfo.c b/src_features/provideNFTInformation/cmd_provideNFTInfo.c
index a9685ce2b..61889d63c 100644
--- a/src_features/provideNFTInformation/cmd_provideNFTInfo.c
+++ b/src_features/provideNFTInformation/cmd_provideNFTInfo.c
@@ -137,7 +137,7 @@ void handleProvideNFTInformation(uint8_t p1,
     offset += CHAIN_ID_SIZE;
 
     uint8_t keyId = workBuffer[offset];
-    uint8_t *rawKey;
+    const uint8_t *rawKey;
     uint8_t rawKeyLen;
 
     PRINTF("KeyID: %d\n", keyId);
@@ -146,7 +146,7 @@ void handleProvideNFTInformation(uint8_t p1,
         case STAGING_NFT_METADATA_KEY:
 #endif
         case PROD_NFT_METADATA_KEY:
-            rawKey = (uint8_t *) LEDGER_NFT_METADATA_PUBLIC_KEY;
+            rawKey = LEDGER_NFT_METADATA_PUBLIC_KEY;
             rawKeyLen = sizeof(LEDGER_NFT_METADATA_PUBLIC_KEY);
             break;
         default:
diff --git a/src_features/signMessage/ui_common_signMessage.c b/src_features/signMessage/ui_common_signMessage.c
index 4bc7da9c1..d58fd6cff 100644
--- a/src_features/signMessage/ui_common_signMessage.c
+++ b/src_features/signMessage/ui_common_signMessage.c
@@ -1,6 +1,6 @@
 #include "os_io_seproxyhal.h"
 #include "apdu_constants.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 #include "common_ui.h"
 
 unsigned int io_seproxyhal_touch_signMessage_ok(void) {
diff --git a/src_features/signMessageEIP712/ui_logic.c b/src_features/signMessageEIP712/ui_logic.c
index 88951d747..54598f162 100644
--- a/src_features/signMessageEIP712/ui_logic.c
+++ b/src_features/signMessageEIP712/ui_logic.c
@@ -17,6 +17,7 @@
 #include "commands_712.h"
 #include "common_ui.h"
 #include "domain_name.h"
+#include "uint_common.h"
 
 static t_ui_context *ui_ctx = NULL;
 
@@ -165,11 +166,10 @@ void ui_712_message_hash(void) {
     const char *const title = "Message hash";
 
     ui_712_set_title(title, strlen(title));
-    snprintf(strings.tmp.tmp,
-             sizeof(strings.tmp.tmp),
-             "0x%.*H",
-             KECCAK256_HASH_BYTESIZE,
-             tmpCtx.messageSigningContext712.messageHash);
+    bytes_to_string(strings.tmp.tmp,
+                    sizeof(strings.tmp.tmp),
+                    tmpCtx.messageSigningContext712.messageHash,
+                    KECCAK256_HASH_BYTESIZE);
     ui_712_redraw_generic_step();
 }
 
@@ -286,7 +286,7 @@ static bool ui_712_format_bool(const uint8_t *const data, uint8_t length) {
  */
 static void ui_712_format_bytes(const uint8_t *const data, uint8_t length) {
     if (ui_712_field_shown()) {
-        snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", length, data);
+        bytes_to_string(strings.tmp.tmp, sizeof(strings.tmp.tmp), data, length);
         // +2 for the "0x"
         // x2 for each byte value is represented by 2 ASCII characters
         if ((2 + (length * 2)) > (sizeof(strings.tmp.tmp) - 1)) {
diff --git a/src_features/signMessageEIP712_common/common_712.c b/src_features/signMessageEIP712_common/common_712.c
index e45e30cbb..95b8866d5 100644
--- a/src_features/signMessageEIP712_common/common_712.c
+++ b/src_features/signMessageEIP712_common/common_712.c
@@ -1,7 +1,7 @@
 #include "shared_context.h"
 #include "apdu_constants.h"
 #include "os_io_seproxyhal.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 #include "ui_callbacks.h"
 #include "common_712.h"
 #include "ui_callbacks.h"
diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c
index 20c137568..08f0938cf 100644
--- a/src_features/signTx/logic_signTx.c
+++ b/src_features/signTx/logic_signTx.c
@@ -8,11 +8,12 @@
 #include "common_ui.h"
 #include "ui_callbacks.h"
 #include "apdu_constants.h"
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
+#include "format.h"
 
 #define ERR_SILENT_MODE_CHECK_FAILED 0x6001
 
-uint32_t splitBinaryParameterPart(char *result, uint8_t *parameter) {
+static uint32_t splitBinaryParameterPart(char *result, size_t result_size, uint8_t *parameter) {
     uint32_t i;
     for (i = 0; i < 8; i++) {
         if (parameter[i] != 0x00) {
@@ -25,7 +26,7 @@ uint32_t splitBinaryParameterPart(char *result, uint8_t *parameter) {
         result[2] = '\0';
         return 2;
     } else {
-        array_hexstr(result, parameter + i, 8 - i);
+        format_hex(parameter + i, 8 - i, result, result_size);
         return ((8 - i) * 2);
     }
 }
@@ -144,7 +145,10 @@ customStatus_e customProcessor(txContext_t *context) {
             }
             dataContext.tokenContext.fieldOffset = 0;
             if (fieldPos == 0) {
-                array_hexstr(strings.tmp.tmp, dataContext.tokenContext.data, 4);
+                format_hex(dataContext.tokenContext.data,
+                           4,
+                           strings.tmp.tmp,
+                           sizeof(strings.tmp.tmp));
                 ui_confirm_selector();
             } else {
                 uint32_t offset = 0;
@@ -155,6 +159,7 @@ customStatus_e customProcessor(txContext_t *context) {
                          dataContext.tokenContext.fieldIndex);
                 for (i = 0; i < 4; i++) {
                     offset += splitBinaryParameterPart(strings.tmp.tmp + offset,
+                                                       sizeof(strings.tmp.tmp) - offset,
                                                        dataContext.tokenContext.data + 8 * i);
                     if (i != 3) {
                         strings.tmp.tmp[offset++] = ':';
diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c
index 96eee2fe2..9041c7012 100644
--- a/src_features/signTx/ui_common_signTx.c
+++ b/src_features/signTx/ui_common_signTx.c
@@ -1,4 +1,4 @@
-#include "lib_standard_app/crypto_helpers.h"
+#include "crypto_helpers.h"
 #include "os_io_seproxyhal.h"
 #include "shared_context.h"
 #include "common_utils.h"
diff --git a/src_nbgl/ui_get_eth2_public_key.c b/src_nbgl/ui_get_eth2_public_key.c
index 3f6a3e70c..09c939b58 100644
--- a/src_nbgl/ui_get_eth2_public_key.c
+++ b/src_nbgl/ui_get_eth2_public_key.c
@@ -2,6 +2,7 @@
 #include "shared_context.h"
 #include "ui_callbacks.h"
 #include "ui_nbgl.h"
+#include "uint_common.h"
 
 static void reviewReject(void) {
     io_seproxyhal_touch_address_cancel(NULL);
@@ -21,7 +22,10 @@ static void reviewChoice(bool confirm) {
 }
 
 static void buildScreen(void) {
-    snprintf(strings.tmp.tmp, 100, "0x%.*H", 48, tmpCtx.publicKeyContext.publicKey.W);
+    bytes_to_string(strings.tmp.tmp,
+                    sizeof(strings.tmp.tmp),
+                    tmpCtx.publicKeyContext.publicKey.W,
+                    48);
     nbgl_useCaseAddressConfirmation(strings.tmp.tmp, reviewChoice);
 }
 
diff --git a/src_nbgl/ui_sign_712_v0.c b/src_nbgl/ui_sign_712_v0.c
index 0681009bc..e0bc71825 100644
--- a/src_nbgl/ui_sign_712_v0.c
+++ b/src_nbgl/ui_sign_712_v0.c
@@ -4,13 +4,14 @@
 #include "network.h"
 #include "ui_message_signing.h"
 #include "ui_signing.h"
+#include "uint_common.h"
 
 static nbgl_layoutTagValue_t pairs[2];
 
 static void start_review(void);  // forward declaration
 
 static char *format_hash(const uint8_t *hash, char *buffer, size_t buffer_size, size_t offset) {
-    snprintf(buffer + offset, buffer_size - offset, "0x%.*H", KECCAK256_HASH_BYTESIZE, hash);
+    bytes_to_string(buffer + offset, buffer_size - offset, hash, KECCAK256_HASH_BYTESIZE);
     return buffer + offset;
 }
 
diff --git a/src_plugin_sdk/CHANGELOG.md b/src_plugin_sdk/CHANGELOG.md
deleted file mode 100644
index 50aba608b..000000000
--- a/src_plugin_sdk/CHANGELOG.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Ethereum Plugin SDK changelog
-
-|          Icon        |            Impact             |
-|----------------------|-------------------------------|
-| :rotating_light:     | Breaks build                  |
-| :warning:            | Breaks compatibility with app |
-
-## [latest](/) - 2024/04/12
-
-### Fixed
-
-* Fix potential oob writes in `amountToString`
-
-## [8fe6572](/../../commit/8fe6572) - 2024/03/27
-
-### Changed
-
-* Add new functions `getEthAddressFromRawKey` and `getEthAddressStringFromRawKey`
-* Simplify crypto calls in `getEthAddressStringFromBinary`
-* Cleanup useless `cx_sha3_t` useless parameter
-
-## [0a98664](/../../commit/0a98664) - 2024/02/07
-
-### Removed
-
-* UI disabler
-
-## [2250549](/../../commit/2250549) - 2024/02/02
-
-### Changed
-
-* The SDK source code has been split into multiple smaller files
-
-## [3b7e7ad](/../../commit/3b7e7ad) - 2023/12/07
-
-### Fixed
-
-* standard\_plugin build ([this PR on the SDK](https://github.com/LedgerHQ/ledger-secure-sdk/pull/473) had broken it)
-* Broken variant auto-setting in the standard\_plugin Makefile
-* Missing null-check on parameters received by the plugins
-
-### Changed
-
-* utils renamed to plugin\_utils to prevent filename conflicts in plugins
-
-## [4d8e044](/../../commit/4d8e044) - 2023/11/09
-
-### Added
-
-* standard\_plugin Makefile so plugins can use it & have a really small Makefile
-with only the relevant information
-* Comments in the plugin interface header file
-
-## [1fe4085](/../../commit/1fe4085) - 2023/10/19
-
-### Changed
-
-* Now only uses *\_no\_throw* functions, SDK functions now return a boolean
-(keeps the guidelines enforcer happy)
-
-### Added
-
-* *main* & *dispatch\_call* functions are now part of the SDK and don't need to
-be implemented by each plugin :rotating_light:
-
-## [b9777e7](/../../commit/b9777e7) - 2023/05/16
-
-### Added
-
-* Stax support with information passed from plugin to app-ethereum (with caller app struct)
-
-## [a4b971f](/../../commit/a4b971f) - 2023/01/24
-
-### Changed
-
-* Removed end space in tickers :warning:
-
-## [81eb658](/../../commit/81eb658) - 2022/11/17
-
-### Added
-
-* *U2BE\_from\_parameter* & *U4BE\_from\_parameter* safe functions
diff --git a/src_plugin_sdk/LICENSE b/src_plugin_sdk/LICENSE
deleted file mode 100644
index 8dada3eda..000000000
--- a/src_plugin_sdk/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/src_plugin_sdk/README.md b/src_plugin_sdk/README.md
deleted file mode 100644
index a5c308d36..000000000
--- a/src_plugin_sdk/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# ethereum-plugin-sdk
-
-This repository is meant to be linked as submodule and used in external plugins working with [app-ethereum](https://github.com/LedgerHQ/app-ethereum).
-It is composed of a few headers containing definitions about app-ethereum's internal transaction parsing state and some structures to communicate via shared memory.
-
-## Updating this SDK
-
-This SDK is updated at (app-ethereum) build time every time one of app-ethereum internals structures of interest are modified.
-If this SDK gets updated, it is possible that all plugins must be recompiled (and eventually updated to work again with the update) with this new SDK.
-Be careful, and weight your choices.
-
-## Manual build
-
-If for some reasons you want to rebuild this SDK manually from [app-ethereum](https://github.com/LedgerHQ/app-ethereum) (reminder: it is rebuild automatically when building app-ethereum itself):
-
-```shell
-$> ./tools/build_sdk.sh
-```
diff --git a/src_plugin_sdk/src/eth_internals.h b/src_plugin_sdk/src/eth_internals.h
deleted file mode 100644
index 60087eabc..000000000
--- a/src_plugin_sdk/src/eth_internals.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*******************************************************************************
- *   Ledger Ethereum App
- *   (c) 2016-2019 Ledger
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- ********************************************************************************/
-
-#pragma once
-
-// Empty file, introduced to not break compatibility following plugin-sdk structure rework
-#warning "Deprecated file, the sdk sources have been rationalized in several dedicated files."
diff --git a/src_plugin_sdk/src/main.c b/src_plugin_sdk/src/main.c
deleted file mode 100644
index bd5b56c10..000000000
--- a/src_plugin_sdk/src/main.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*****************************************************************************
- *   Ledger Plugin SDK
- *   (c) 2023 Ledger SAS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *****************************************************************************/
-
-#include "eth_plugin_interface.h"
-#include "lib_standard_app/swap_lib_calls.h"  // RUN_APPLICATION
-
-// Functions implemented by the plugin
-void handle_init_contract(ethPluginInitContract_t *parameters);
-void handle_provide_parameter(ethPluginProvideParameter_t *parameters);
-void handle_finalize(ethPluginFinalize_t *parameters);
-void handle_provide_token(ethPluginProvideInfo_t *parameters);
-void handle_query_contract_id(ethQueryContractID_t *parameters);
-void handle_query_contract_ui(ethQueryContractUI_t *parameters);
-
-// Calls the ethereum app.
-static void call_app_ethereum() {
-    unsigned int libcall_params[5];
-    libcall_params[0] = (unsigned int) "Ethereum";
-    libcall_params[1] = 0x100;
-    libcall_params[2] = RUN_APPLICATION;
-    libcall_params[3] = (unsigned int) NULL;
-#ifdef HAVE_NBGL
-    caller_app_t capp;
-    const char name[] = APPNAME;
-    nbgl_icon_details_t icon_details;
-    uint8_t bitmap[sizeof(ICONBITMAP)];
-
-    memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH));
-    memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap));
-    icon_details.bitmap = (const uint8_t *) bitmap;
-    capp.name = (const char *) name;
-    capp.icon = &icon_details;
-    libcall_params[4] = (unsigned int) &capp;
-#else
-    libcall_params[4] = (unsigned int) NULL;
-#endif
-    os_lib_call((unsigned int *) &libcall_params);
-}
-
-// Function to dispatch calls from the ethereum app.
-static void dispatch_call(int message, void *parameters) {
-    if (parameters != NULL) {
-        switch (message) {
-            case ETH_PLUGIN_INIT_CONTRACT:
-                handle_init_contract(parameters);
-                break;
-            case ETH_PLUGIN_PROVIDE_PARAMETER:
-                handle_provide_parameter(parameters);
-                break;
-            case ETH_PLUGIN_FINALIZE:
-                handle_finalize(parameters);
-                break;
-            case ETH_PLUGIN_PROVIDE_INFO:
-                handle_provide_token(parameters);
-                break;
-            case ETH_PLUGIN_QUERY_CONTRACT_ID:
-                handle_query_contract_id(parameters);
-                break;
-            case ETH_PLUGIN_QUERY_CONTRACT_UI:
-                handle_query_contract_ui(parameters);
-                break;
-            default:
-                PRINTF("Unhandled message %d\n", message);
-                break;
-        }
-    } else {
-        PRINTF("Received null parameters\n");
-    }
-}
-
-// Low-level main for plugins.
-__attribute__((section(".boot"))) int main(int arg0) {
-    // Exit critical section
-    __asm volatile("cpsie i");
-
-    os_boot();
-
-    BEGIN_TRY {
-        TRY {
-            // Check if plugin is called from the dashboard.
-            if (!arg0) {
-                // Called from dashboard, launch Ethereum app
-                call_app_ethereum();
-
-                // Will not get reached.
-                __builtin_unreachable();
-
-                os_sched_exit(-1);
-
-            } else {
-                // Not called from dashboard: called from the ethereum app!
-                const unsigned int *args = (unsigned int *) arg0;
-
-                // If `ETH_PLUGIN_CHECK_PRESENCE` is set, this means the caller is just trying to
-                // know whether this app exists or not. We can skip `paraswap_plugin_call`.
-                if (args[0] != ETH_PLUGIN_CHECK_PRESENCE) {
-                    dispatch_call(args[0], (void *) args[1]);
-                }
-            }
-
-            // Call `os_lib_end`, go back to the ethereum app.
-            os_lib_end();
-
-            // Will not get reached.
-            __builtin_unreachable();
-        }
-        CATCH_OTHER(e) {
-            PRINTF("Exiting following exception: %d\n", e);
-        }
-        FINALLY {
-            os_lib_end();
-        }
-    }
-    END_TRY;
-}
diff --git a/src_plugin_sdk/standard_plugin.mk b/src_plugin_sdk/standard_plugin.mk
deleted file mode 100644
index f52c1327e..000000000
--- a/src_plugin_sdk/standard_plugin.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# ****************************************************************************
-#    Ledger Ethereum Plugin SDK
-#    (c) 2023 Ledger SAS.
-#
-#   Licensed under the Apache License, Version 2.0 (the "License");
-#   you may not use this file except in compliance with the License.
-#   You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS,
-#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#   See the License for the specific language governing permissions and
-#   limitations under the License.
-# ****************************************************************************
-
-ifeq ($(BOLOS_SDK),)
-$(error Environment variable BOLOS_SDK is not set)
-endif
-
-include $(BOLOS_SDK)/Makefile.defines
-
-APPVERSION ?= "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"
-
-# Application source files
-APP_SOURCE_PATH += src ethereum-plugin-sdk
-
-# Application icons following guidelines:
-# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon
-NORMAL_NAME ?= $(shell echo -n "$(APPNAME)" | tr " ." "_" | tr "[:upper:]" "[:lower:]")
-ICON_NANOS = icons/nanos_app_$(NORMAL_NAME).gif
-ICON_NANOX = icons/nanox_app_$(NORMAL_NAME).gif
-ICON_NANOSP = $(ICON_NANOX)
-ICON_STAX = icons/stax_app_$(NORMAL_NAME).gif
-
-ifeq ($(TARGET_NAME),TARGET_STAX)
-    DEFINES += ICONGLYPH=C_stax_$(NORMAL_NAME)_64px
-    DEFINES += ICONBITMAP=C_stax_$(NORMAL_NAME)_64px_bitmap
-endif
-
-CURVE_APP_LOAD_PARAMS = secp256k1
-
-PATH_APP_LOAD_PARAMS ?= "44'/60'"
-
-VARIANT_PARAM = COIN
-VARIANT_VALUES ?= $(NORMAL_NAME)
-
-HAVE_APPLICATION_FLAG_LIBRARY = 1
-
-DISABLE_STANDARD_APP_FILES = 1
-DISABLE_STANDARD_SNPRINTF = 1
-DISABLE_STANDARD_USB = 1
-DISABLE_STANDARD_WEBUSB = 1
-DISABLE_STANDARD_BAGL_UX_FLOW = 1
-DISABLE_DEBUG_LEDGER_ASSERT = 1
-DISABLE_DEBUG_THROW = 1
-
-include $(BOLOS_SDK)/Makefile.standard_app
diff --git a/src_plugins/erc1155/erc1155_plugin.c b/src_plugins/erc1155/erc1155_plugin.c
index b81aa8d5c..b1704ca2a 100644
--- a/src_plugins/erc1155/erc1155_plugin.c
+++ b/src_plugins/erc1155/erc1155_plugin.c
@@ -27,7 +27,7 @@ static void handle_init_contract(void *parameters) {
     }
     uint8_t i;
     for (i = 0; i < SELECTORS_COUNT; i++) {
-        if (memcmp((uint8_t *) PIC(ERC1155_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == 0) {
+        if (memcmp(PIC(ERC1155_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == 0) {
             context->selectorIndex = i;
             break;
         }
diff --git a/src_plugins/erc20/erc20_plugin.c b/src_plugins/erc20/erc20_plugin.c
index c10497400..009336f61 100644
--- a/src_plugins/erc20/erc20_plugin.c
+++ b/src_plugins/erc20/erc20_plugin.c
@@ -64,7 +64,7 @@ const contract_t CONTRACTS[NUM_CONTRACTS] = {
 
 bool check_contract(erc20_parameters_t *context) {
     for (size_t i = 0; i < NUM_CONTRACTS; i++) {
-        contract_t *contract = (contract_t *) PIC(&CONTRACTS[i]);
+        const contract_t *contract = (const contract_t *) PIC(&CONTRACTS[i]);
         if (memcmp(contract->address, context->destinationAddress, ADDRESS_LENGTH) == 0) {
             strlcpy(context->contract_name, contract->name, sizeof(context->contract_name));
             return true;
diff --git a/src_plugins/erc721/erc721_plugin.c b/src_plugins/erc721/erc721_plugin.c
index bfe12cd9d..07ba0c7a6 100644
--- a/src_plugins/erc721/erc721_plugin.c
+++ b/src_plugins/erc721/erc721_plugin.c
@@ -32,7 +32,7 @@ static void handle_init_contract(void *parameters) {
     }
     uint8_t i;
     for (i = 0; i < SELECTORS_COUNT; i++) {
-        if (memcmp((uint8_t *) PIC(ERC721_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == 0) {
+        if (memcmp(PIC(ERC721_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == 0) {
             context->selectorIndex = i;
             break;
         }
diff --git a/src_plugins/eth2/eth2_plugin.c b/src_plugins/eth2/eth2_plugin.c
index c18462a8e..9c42e3134 100644
--- a/src_plugins/eth2/eth2_plugin.c
+++ b/src_plugins/eth2/eth2_plugin.c
@@ -199,7 +199,7 @@ void eth2_plugin_call(int message, void *parameters) {
             switch (msg->screenIndex) {
                 case 0: {  // Amount screen
                     uint8_t decimals = WEI_TO_ETHER;
-                    char *ticker = chainConfig->coinName;
+                    const char *ticker = chainConfig->coinName;
                     strlcpy(msg->title, "Amount", msg->titleLength);
                     if (!amountToString(tmpContent.txContent.value.value,
                                         tmpContent.txContent.value.length,
diff --git a/tools/build_sdk.sh b/tools/build_sdk.sh
deleted file mode 100755
index f4ec6a382..000000000
--- a/tools/build_sdk.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-# Clean the sdk
-find ./ethereum-plugin-sdk/ -mindepth 1 -maxdepth 1 ! -name .git -exec rm -r {} \;
-
-# Copy exclusive files
-cp -r src_plugin_sdk/* ./ethereum-plugin-sdk/
-
-# Copy common sources
-cp -r src_common/* ./ethereum-plugin-sdk/src/


Test patch:
diff --git a/makefile_conf/chain/rsk_testnet.mk b/makefile_conf/chain/rsk_testnet.mk
index 8caa3a7f6..0e043e49d 100644
--- a/makefile_conf/chain/rsk_testnet.mk
+++ b/makefile_conf/chain/rsk_testnet.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/37310'"
+PATH_APP_LOAD_PARAMS += "44'/37310'"
 TICKER = "RBTC"
 CHAIN_ID = 31
 APPNAME = "RSK Test"
diff --git a/makefile_conf/chain/tecratestnet.mk b/makefile_conf/chain/tecratestnet.mk
index 1be7c068b..b778ca1ba 100644
--- a/makefile_conf/chain/tecratestnet.mk
+++ b/makefile_conf/chain/tecratestnet.mk
@@ -1,4 +1,4 @@
-APP_LOAD_PARAMS += --path "44'/554'"  --path "44'/60'"
+PATH_APP_LOAD_PARAMS += "44'/554'" "44'/60'"
 TICKER = "TCR"
 CHAIN_ID = 20531811
 APPNAME = "TecraTestnet"
diff --git a/tests/ragger/snapshots/nanos/test_legacy_contract/00000.png b/tests/ragger/snapshots/nanos/test_legacy_contract/00000.png
deleted file mode 100644
index c2420afe1..000000000
Binary files a/tests/ragger/snapshots/nanos/test_legacy_contract/00000.png and /dev/null differ
diff --git a/tests/ragger/snapshots/nanos/test_legacy_contract/00001.png b/tests/ragger/snapshots/nanos/test_legacy_contract/00001.png
deleted file mode 100644
index b31e45596..000000000
Binary files a/tests/ragger/snapshots/nanos/test_legacy_contract/00001.png and /dev/null differ
diff --git a/tests/ragger/snapshots/nanos/test_legacy_contract/00002.png b/tests/ragger/snapshots/nanos/test_legacy_contract/00002.png
deleted file mode 100644
index ce795f34e..000000000
Binary files a/tests/ragger/snapshots/nanos/test_legacy_contract/00002.png and /dev/null differ
diff --git a/tests/ragger/snapshots/nanosp/test_legacy_contract b/tests/ragger/snapshots/nanosp/test_legacy_contract
deleted file mode 120000
index ab2ec19ea..000000000
--- a/tests/ragger/snapshots/nanosp/test_legacy_contract
+++ /dev/null
@@ -1,1 +0,0 @@
-../nanox/test_legacy_contract
\ No newline at end of file
diff --git a/tests/ragger/snapshots/nanox/test_legacy_contract/00000.png b/tests/ragger/snapshots/nanox/test_legacy_contract/00000.png
deleted file mode 100644
index 0446ee754..000000000
Binary files a/tests/ragger/snapshots/nanox/test_legacy_contract/00000.png and /dev/null differ
diff --git a/tests/ragger/snapshots/nanox/test_legacy_contract/00001.png b/tests/ragger/snapshots/nanox/test_legacy_contract/00001.png
deleted file mode 100644
index a58590b98..000000000
Binary files a/tests/ragger/snapshots/nanox/test_legacy_contract/00001.png and /dev/null differ
diff --git a/tests/ragger/test_sign.py b/tests/ragger/test_sign.py
index 48a0fbe53..6b82cb238 100644
--- a/tests/ragger/test_sign.py
+++ b/tests/ragger/test_sign.py
@@ -180,26 +180,13 @@ def test_legacy_chainid(firmware: Firmware,
 
 
 # Try to blind sign with setting disabled
-def test_legacy_contract(firmware: Firmware,
-                         backend: BackendInterface,
-                         navigator: Navigator,
-                         test_name: str,
-                         default_screenshot_path: Path):
+def test_legacy_contract(backend: BackendInterface):
 
     buffer = bytes.fromhex("058000002c8000003c800000010000000000000000f849208506fc23ac008303dc3194f650c3d88d12db855b8bf7d11be6c55a4e07dcc980a4a1712d6800000000000000000000000000000000000000000000000000000000000acbc7018080")
     app_client = EthAppClient(backend)
 
     try:
-        with app_client.send_raw(0xe0, 0x04, 0x00, 0x00, buffer):
-            if firmware.device.startswith("nano"):
-                # No screens recorded on Stax
-                moves = [
-                    NavInsID.RIGHT_CLICK,
-                    NavInsID.BOTH_CLICK
-                ]
-                navigator.navigate_and_compare(default_screenshot_path,
-                                               test_name,
-                                               moves)
+        app_client.send_raw(0xe0, 0x04, 0x00, 0x00, buffer)
 
     except ExceptionRAPDU as e:
         assert e.status == StatusWord.INVALID_DATA
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index 3683680a9..305b13bbb 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -52,7 +52,6 @@ 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)
diff --git a/tests/unit/Makefile b/tests/unit/Makefile
index 91d1bfd1b..73f39e410 100644
--- a/tests/unit/Makefile
+++ b/tests/unit/Makefile
@@ -27,7 +27,7 @@ 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/*'
+	@lcov --directory . -b "${BUILD_DIRECTORY}" --remove coverage.info '*/tests/unit/*' -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;