diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 711779d18..a141a2d83 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -15,7 +15,7 @@ Describe your issue in as much detail as possible here.
* OS and version
* branch that causes this issue
-* Device (Nano S, Nano X, Ledger Blue)
+* Device (Nano S, Nano S Plus, Nano X, Ledger Blue)
## Steps to reproduce
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index f8abc5224..031ba337d 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -15,4 +15,4 @@ Describe your issue in as much detail as possible here.
* OS and version
* branch that causes this issue
-* Device (Nano S, Nano X, Ledger Blue)
\ No newline at end of file
+* Device (Nano S, Nano S Plus, Nano X, Ledger Blue)
diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml
index 3e15b7913..d5cf7959e 100644
--- a/.github/workflows/ci-workflow.yml
+++ b/.github/workflows/ci-workflow.yml
@@ -128,6 +128,7 @@ jobs:
jobs-e2e-speculos-tests:
name: Speculos tests
strategy:
+ fail-fast: false
matrix:
model: ["nanosp", "nanos", "nanox"]
@@ -153,7 +154,7 @@ jobs:
run: |
cd tests/speculos
sudo apt-get update && sudo apt-get install -y qemu-user-static
- pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt
+ pip install -r requirements.txt
- name: Run speculos tests
run: |
@@ -171,7 +172,6 @@ jobs:
with:
upload_app_binaries_artifact: "ragger_elfs"
flags: "DEBUG=1 CAL_CI_KEY=1 DOMAIN_NAME_TEST_KEY=1"
- run_for_devices: '["nanos", "nanox", "nanosp"]'
jobs-ragger-tests:
name: Run Ragger tests
@@ -180,4 +180,3 @@ jobs:
with:
download_app_binaries_artifact: "ragger_elfs"
test_dir: tests/ragger
- run_for_devices: '["nanos", "nanox", "nanosp"]'
diff --git a/.github/workflows/swap-ci-workflow.yml b/.github/workflows/swap-ci-workflow.yml
new file mode 100644
index 000000000..3999224cf
--- /dev/null
+++ b/.github/workflows/swap-ci-workflow.yml
@@ -0,0 +1,16 @@
+name: Swap functional tests
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ - develop
+ pull_request:
+
+jobs:
+ job_functional_tests:
+ uses: LedgerHQ/app-exchange/.github/workflows/reusable_swap_functional_tests.yml@develop
+ with:
+ branch_for_ethereum: ${{ github.ref }}
+ test_filter: '"ETH or eth or Ethereum or ethereum"'
diff --git a/.gitignore b/.gitignore
index 9443644b5..6779287da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ bin/
debug/
dep/
obj/
+build/
# Python
*.pyc
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 50c74f734..6cd99025a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [1.10.3](https://github.com/ledgerhq/app-ethereum/compare/1.10.2...1.10.3) - 2023-07-27
+
+### Added
+
+- (network) LUKSO mainnet & testnet
+- (network) Chiado
+- (network) PulseChain
+- (network) Neon EVM mainnet & devnet
+- (network) Venidium
+- (network) Telos EVM mainnet
+- (network) OKBChain mainnet
+- (network) Polygon zkEVM
+- (network) Base
+- (network) Sepolia
+- ENS on chains that share the Ethereum derivation path
+- Ledger Stax support
+
+### Changed
+
+- (network) xDai renamed to Gnosis
+
+### Fixed
+
+- Missing context cleanup between plugin calls
+- Miscellaneous swap issues
+- Improper EIP-712 array handling
+
## [1.10.2](https://github.com/ledgerhq/app-ethereum/compare/1.10.1...1.10.2) - 2023-04-24
### Added
diff --git a/Makefile b/Makefile
index b7704d763..4715da52a 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
APPVERSION_M=1
APPVERSION_N=10
-APPVERSION_P=2
+APPVERSION_P=3
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
APP_LOAD_FLAGS= --appFlags 0xa40 --dep Ethereum:$(APPVERSION)
@@ -54,6 +54,7 @@ include ./makefile_conf/chain/$(CHAIN).mk
else
$(error Unsupported CHAIN - use $(SUPPORTED_CHAINS))
endif
+CFLAGS += -DAPPNAME=\"$(APPNAME)\"
#########
# Other #
@@ -65,6 +66,12 @@ DEFINES += $(DEFINES_LIB)
#prepare hsm generation
ifeq ($(TARGET_NAME),TARGET_NANOS)
ICONNAME=icons/nanos_app_$(CHAIN).gif
+else ifeq ($(TARGET_NAME),TARGET_STAX)
+ICONNAME=icons/stax_app_$(CHAIN).gif
+DEFINES += ICONGLYPH=C_stax_$(CHAIN)_64px
+DEFINES += ICONBITMAP=C_stax_$(CHAIN)_64px_bitmap
+DEFINES += ICONGLYPH_SMALL=C_stax_$(CHAIN)
+GLYPH_FILES += $(ICONNAME)
else
ICONNAME=icons/nanox_app_$(CHAIN).gif
endif
@@ -79,9 +86,10 @@ all: default
############
DEFINES += OS_IO_SEPROXYHAL
-DEFINES += HAVE_BAGL HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U
+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
@@ -90,30 +98,41 @@ DEFINES += USB_SEGMENT_SIZE=64
DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20
DEFINES += UNUSED\(x\)=\(void\)x
DEFINES += APPVERSION=\"$(APPVERSION)\"
-DEFINES += HAVE_UX_FLOW
#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=""
-ifeq ($(TARGET_NAME),TARGET_NANOX)
+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=72
-DEFINES += HAVE_WALLET_ID_SDK
+DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
+endif
+
+ifeq ($(TARGET_NAME),TARGET_STAX)
+DEFINES += NBGL_QRCODE
+else
+DEFINES += HAVE_BAGL
+DEFINES += HAVE_UX_FLOW
+ifeq ($(TARGET_NAME),TARGET_NANOS)
+DEFINES += HAVE_WALLET_ID_SDK
+DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=32
+else
DEFINES += HAVE_GLO096
-DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64
+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
# Enables direct data signing without having to specify it in the settings. Useful when testing with speculos.
ALLOW_DATA:=0
@@ -167,7 +186,6 @@ endif
endif
# Enabling debug PRINTF
-DEBUG:=0
ifneq ($(DEBUG),0)
DEFINES += HAVE_STACK_OVERFLOW_CHECK
ifeq ($(TARGET_NAME),TARGET_NANOS)
@@ -204,13 +222,11 @@ endif
CC := $(CLANGPATH)clang
-#CFLAGS += -O0
-CFLAGS += -Oz -Wno-format-invalid-specifier -Wno-format-extra-args
+CFLAGS += -Wno-format-invalid-specifier -Wno-format-extra-args
AS := $(GCCPATH)arm-none-eabi-gcc
LD := $(GCCPATH)arm-none-eabi-gcc
-LDFLAGS += -O3 -Os
LDLIBS += -lm -lgcc -lc
# import rules to compile glyphs(/pone)
@@ -219,11 +235,12 @@ include $(BOLOS_SDK)/Makefile.glyphs
### 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)
+APP_SOURCE_PATH += src_nbgl
+else
SDK_SOURCE_PATH += lib_ux
-ifeq ($(TARGET_NAME),TARGET_NANOX)
-SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
-endif
APP_SOURCE_PATH += src_bagl
+endif
### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed
ifeq ($(CHAIN),ethereum)
diff --git a/README.md b/README.md
index 789a604aa..0293c3194 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
app-ethereum
- Ethereum wallet application for Ledger Blue, Nano S and Nano X
+ Ethereum wallet application for Ledger Blue, Nano S, Nano S Plus and Nano X
« Explore the docs »
@@ -42,7 +42,7 @@
## About the project
-Ethereum wallet application framework for Nano S and Nano X.
+Ethereum wallet application framework for Nano S, Nano S Plus and Nano X.
Ledger Blue is not maintained anymore, but the app can still be compiled for this target using the branch [`blue-final-release`](https://github.com/LedgerHQ/app-ethereum/tree/blue-final-release).
## Documentation
diff --git a/ethereum-plugin-sdk b/ethereum-plugin-sdk
index a4b971f67..b9777e7a8 160000
--- a/ethereum-plugin-sdk
+++ b/ethereum-plugin-sdk
@@ -1 +1 @@
-Subproject commit a4b971f67980694d8c3862e793859209bc525545
+Subproject commit b9777e7a81a9c33b3f8997ffa23396fa2b3f861d
diff --git a/glyphs/badge_transaction.gif b/glyphs/badge_transaction.gif
deleted file mode 100644
index 131325d4a..000000000
Binary files a/glyphs/badge_transaction.gif and /dev/null differ
diff --git a/glyphs/blue_badge_akroma.gif b/glyphs/blue_badge_akroma.gif
deleted file mode 100644
index 40b3320c4..000000000
Binary files a/glyphs/blue_badge_akroma.gif and /dev/null differ
diff --git a/glyphs/blue_badge_atheios.gif b/glyphs/blue_badge_atheios.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_atheios.gif and /dev/null differ
diff --git a/glyphs/blue_badge_callisto.gif b/glyphs/blue_badge_callisto.gif
deleted file mode 100644
index 43a8c3563..000000000
Binary files a/glyphs/blue_badge_callisto.gif and /dev/null differ
diff --git a/glyphs/blue_badge_dexon.gif b/glyphs/blue_badge_dexon.gif
deleted file mode 100644
index 9b4dd9e7c..000000000
Binary files a/glyphs/blue_badge_dexon.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ellaism.gif b/glyphs/blue_badge_ellaism.gif
deleted file mode 100644
index cb4d811e4..000000000
Binary files a/glyphs/blue_badge_ellaism.gif and /dev/null differ
diff --git a/glyphs/blue_badge_eosclassic.gif b/glyphs/blue_badge_eosclassic.gif
deleted file mode 100644
index 3ad0bbaad..000000000
Binary files a/glyphs/blue_badge_eosclassic.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ether1.gif b/glyphs/blue_badge_ether1.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_ether1.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ethereum.gif b/glyphs/blue_badge_ethereum.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_ethereum.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ethereum_classic.gif b/glyphs/blue_badge_ethereum_classic.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_ethereum_classic.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ethergem.gif b/glyphs/blue_badge_ethergem.gif
deleted file mode 100644
index 01676ade0..000000000
Binary files a/glyphs/blue_badge_ethergem.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ethersocial.gif b/glyphs/blue_badge_ethersocial.gif
deleted file mode 100644
index 011545f63..000000000
Binary files a/glyphs/blue_badge_ethersocial.gif and /dev/null differ
diff --git a/glyphs/blue_badge_expanse.gif b/glyphs/blue_badge_expanse.gif
deleted file mode 100644
index 9de8e125c..000000000
Binary files a/glyphs/blue_badge_expanse.gif and /dev/null differ
diff --git a/glyphs/blue_badge_gochain.gif b/glyphs/blue_badge_gochain.gif
deleted file mode 100644
index 4a8ea11eb..000000000
Binary files a/glyphs/blue_badge_gochain.gif and /dev/null differ
diff --git a/glyphs/blue_badge_hpb.gif b/glyphs/blue_badge_hpb.gif
deleted file mode 100644
index 3b64b0c2a..000000000
Binary files a/glyphs/blue_badge_hpb.gif and /dev/null differ
diff --git a/glyphs/blue_badge_mix.gif b/glyphs/blue_badge_mix.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_mix.gif and /dev/null differ
diff --git a/glyphs/blue_badge_musicoin.gif b/glyphs/blue_badge_musicoin.gif
deleted file mode 100644
index c56081dfc..000000000
Binary files a/glyphs/blue_badge_musicoin.gif and /dev/null differ
diff --git a/glyphs/blue_badge_pirl.gif b/glyphs/blue_badge_pirl.gif
deleted file mode 100644
index 19a25f9ff..000000000
Binary files a/glyphs/blue_badge_pirl.gif and /dev/null differ
diff --git a/glyphs/blue_badge_poa.gif b/glyphs/blue_badge_poa.gif
deleted file mode 100644
index 62d6c065b..000000000
Binary files a/glyphs/blue_badge_poa.gif and /dev/null differ
diff --git a/glyphs/blue_badge_reosc.gif b/glyphs/blue_badge_reosc.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_reosc.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ropsten.gif b/glyphs/blue_badge_ropsten.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_ropsten.gif and /dev/null differ
diff --git a/glyphs/blue_badge_rsk.gif b/glyphs/blue_badge_rsk.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_rsk.gif and /dev/null differ
diff --git a/glyphs/blue_badge_rsk_testnet.gif b/glyphs/blue_badge_rsk_testnet.gif
deleted file mode 100644
index 5174214f3..000000000
Binary files a/glyphs/blue_badge_rsk_testnet.gif and /dev/null differ
diff --git a/glyphs/blue_badge_thundercore.gif b/glyphs/blue_badge_thundercore.gif
deleted file mode 100644
index a31bbe32d..000000000
Binary files a/glyphs/blue_badge_thundercore.gif and /dev/null differ
diff --git a/glyphs/blue_badge_tomochain.gif b/glyphs/blue_badge_tomochain.gif
deleted file mode 100644
index 624837f5a..000000000
Binary files a/glyphs/blue_badge_tomochain.gif and /dev/null differ
diff --git a/glyphs/blue_badge_ubiq.gif b/glyphs/blue_badge_ubiq.gif
deleted file mode 100644
index 69b1cf3ae..000000000
Binary files a/glyphs/blue_badge_ubiq.gif and /dev/null differ
diff --git a/glyphs/blue_badge_wanchain.gif b/glyphs/blue_badge_wanchain.gif
deleted file mode 100644
index deb64841e..000000000
Binary files a/glyphs/blue_badge_wanchain.gif and /dev/null differ
diff --git a/glyphs/blue_badge_webchain.gif b/glyphs/blue_badge_webchain.gif
deleted file mode 100644
index 24edd1c2a..000000000
Binary files a/glyphs/blue_badge_webchain.gif and /dev/null differ
diff --git a/glyphs/icon_back.gif b/glyphs/icon_back.gif
deleted file mode 100644
index a2a7e6d4f..000000000
Binary files a/glyphs/icon_back.gif and /dev/null differ
diff --git a/glyphs/icon_back_x.gif b/glyphs/icon_back_x.gif
deleted file mode 100644
index ff043615c..000000000
Binary files a/glyphs/icon_back_x.gif and /dev/null differ
diff --git a/glyphs/icon_certificate.gif b/glyphs/icon_certificate.gif
deleted file mode 100644
index 89b529f79..000000000
Binary files a/glyphs/icon_certificate.gif and /dev/null differ
diff --git a/glyphs/icon_crossmark.gif b/glyphs/icon_crossmark.gif
deleted file mode 100644
index 2dcf9d9ee..000000000
Binary files a/glyphs/icon_crossmark.gif and /dev/null differ
diff --git a/glyphs/icon_dashboard.gif b/glyphs/icon_dashboard.gif
deleted file mode 100644
index 5c305517f..000000000
Binary files a/glyphs/icon_dashboard.gif and /dev/null differ
diff --git a/glyphs/icon_dashboard_x.gif b/glyphs/icon_dashboard_x.gif
deleted file mode 100644
index 33d9b0a74..000000000
Binary files a/glyphs/icon_dashboard_x.gif and /dev/null differ
diff --git a/glyphs/icon_down.gif b/glyphs/icon_down.gif
deleted file mode 100644
index 4f4e39ee3..000000000
Binary files a/glyphs/icon_down.gif and /dev/null differ
diff --git a/glyphs/icon_eye.gif b/glyphs/icon_eye.gif
deleted file mode 100644
index df4bb829e..000000000
Binary files a/glyphs/icon_eye.gif and /dev/null differ
diff --git a/glyphs/icon_left.gif b/glyphs/icon_left.gif
deleted file mode 100644
index 524226ba1..000000000
Binary files a/glyphs/icon_left.gif and /dev/null differ
diff --git a/glyphs/icon_right.gif b/glyphs/icon_right.gif
deleted file mode 100644
index 15ff3cf59..000000000
Binary files a/glyphs/icon_right.gif and /dev/null differ
diff --git a/glyphs/icon_toggle_reset.gif b/glyphs/icon_toggle_reset.gif
deleted file mode 100644
index 450bc869d..000000000
Binary files a/glyphs/icon_toggle_reset.gif and /dev/null differ
diff --git a/glyphs/icon_toggle_set.gif b/glyphs/icon_toggle_set.gif
deleted file mode 100644
index 571264c79..000000000
Binary files a/glyphs/icon_toggle_set.gif and /dev/null differ
diff --git a/glyphs/icon_up.gif b/glyphs/icon_up.gif
deleted file mode 100644
index 4e13c064f..000000000
Binary files a/glyphs/icon_up.gif and /dev/null differ
diff --git a/glyphs/icon_validate_14.gif b/glyphs/icon_validate_14.gif
deleted file mode 100644
index ccb5cabe3..000000000
Binary files a/glyphs/icon_validate_14.gif and /dev/null differ
diff --git a/glyphs/icon_warning.gif b/glyphs/icon_warning.gif
deleted file mode 100644
index 08bd4a739..000000000
Binary files a/glyphs/icon_warning.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_akroma.gif b/glyphs/nanos_badge_akroma.gif
deleted file mode 100644
index 9dfdea6ed..000000000
Binary files a/glyphs/nanos_badge_akroma.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_artis_sigma1.gif b/glyphs/nanos_badge_artis_sigma1.gif
deleted file mode 100644
index 3ef0eaa6f..000000000
Binary files a/glyphs/nanos_badge_artis_sigma1.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_artis_tau1.gif b/glyphs/nanos_badge_artis_tau1.gif
deleted file mode 100644
index 9e741b54e..000000000
Binary files a/glyphs/nanos_badge_artis_tau1.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_atheios.gif b/glyphs/nanos_badge_atheios.gif
deleted file mode 100644
index e7447fadc..000000000
Binary files a/glyphs/nanos_badge_atheios.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_callisto.gif b/glyphs/nanos_badge_callisto.gif
deleted file mode 100644
index 25a0cddfe..000000000
Binary files a/glyphs/nanos_badge_callisto.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_dexon.gif b/glyphs/nanos_badge_dexon.gif
deleted file mode 100644
index 65021cc8c..000000000
Binary files a/glyphs/nanos_badge_dexon.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ellaism.gif b/glyphs/nanos_badge_ellaism.gif
deleted file mode 100644
index d07bad78f..000000000
Binary files a/glyphs/nanos_badge_ellaism.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ether1.gif b/glyphs/nanos_badge_ether1.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_ether1.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ethereum.gif b/glyphs/nanos_badge_ethereum.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_ethereum.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ethereum_classic.gif b/glyphs/nanos_badge_ethereum_classic.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_ethereum_classic.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ethergem.gif b/glyphs/nanos_badge_ethergem.gif
deleted file mode 100644
index 19b762159..000000000
Binary files a/glyphs/nanos_badge_ethergem.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ethersocial.gif b/glyphs/nanos_badge_ethersocial.gif
deleted file mode 100644
index 21262eba8..000000000
Binary files a/glyphs/nanos_badge_ethersocial.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_expanse.gif b/glyphs/nanos_badge_expanse.gif
deleted file mode 100644
index b1c996dba..000000000
Binary files a/glyphs/nanos_badge_expanse.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_gochain.gif b/glyphs/nanos_badge_gochain.gif
deleted file mode 100644
index 39ed2fb3f..000000000
Binary files a/glyphs/nanos_badge_gochain.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_hpb.gif b/glyphs/nanos_badge_hpb.gif
deleted file mode 100644
index ee2a1f0c8..000000000
Binary files a/glyphs/nanos_badge_hpb.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_kusd.gif b/glyphs/nanos_badge_kusd.gif
deleted file mode 100644
index b1ac932b7..000000000
Binary files a/glyphs/nanos_badge_kusd.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_mix.gif b/glyphs/nanos_badge_mix.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_mix.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_musicoin.gif b/glyphs/nanos_badge_musicoin.gif
deleted file mode 100644
index b8288acd0..000000000
Binary files a/glyphs/nanos_badge_musicoin.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_pirl.gif b/glyphs/nanos_badge_pirl.gif
deleted file mode 100644
index ab21513c4..000000000
Binary files a/glyphs/nanos_badge_pirl.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_poa.gif b/glyphs/nanos_badge_poa.gif
deleted file mode 100644
index e45186609..000000000
Binary files a/glyphs/nanos_badge_poa.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_reosc.gif b/glyphs/nanos_badge_reosc.gif
deleted file mode 100644
index fe388baea..000000000
Binary files a/glyphs/nanos_badge_reosc.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ropsten.gif b/glyphs/nanos_badge_ropsten.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_ropsten.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_rsk.gif b/glyphs/nanos_badge_rsk.gif
deleted file mode 100644
index 5ca99a56e..000000000
Binary files a/glyphs/nanos_badge_rsk.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_rsk_testnet.gif b/glyphs/nanos_badge_rsk_testnet.gif
deleted file mode 100644
index 776f6454b..000000000
Binary files a/glyphs/nanos_badge_rsk_testnet.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_thundercore.gif b/glyphs/nanos_badge_thundercore.gif
deleted file mode 100644
index e72367907..000000000
Binary files a/glyphs/nanos_badge_thundercore.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_tomochain.gif b/glyphs/nanos_badge_tomochain.gif
deleted file mode 100644
index f33c2ba01..000000000
Binary files a/glyphs/nanos_badge_tomochain.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_ubiq.gif b/glyphs/nanos_badge_ubiq.gif
deleted file mode 100644
index d2ce45c40..000000000
Binary files a/glyphs/nanos_badge_ubiq.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_wanchain.gif b/glyphs/nanos_badge_wanchain.gif
deleted file mode 100644
index 53bdccdde..000000000
Binary files a/glyphs/nanos_badge_wanchain.gif and /dev/null differ
diff --git a/glyphs/nanos_badge_webchain.gif b/glyphs/nanos_badge_webchain.gif
deleted file mode 100644
index 515eed39f..000000000
Binary files a/glyphs/nanos_badge_webchain.gif and /dev/null differ
diff --git a/glyphs/stax_akroma_64px.gif b/glyphs/stax_akroma_64px.gif
new file mode 100644
index 000000000..d092851df
Binary files /dev/null and b/glyphs/stax_akroma_64px.gif differ
diff --git a/glyphs/stax_apothemnetwork_64px.gif b/glyphs/stax_apothemnetwork_64px.gif
new file mode 100644
index 000000000..974f8bb31
Binary files /dev/null and b/glyphs/stax_apothemnetwork_64px.gif differ
diff --git a/glyphs/stax_artis_sigma1_64px.gif b/glyphs/stax_artis_sigma1_64px.gif
new file mode 100644
index 000000000..05c4f221c
Binary files /dev/null and b/glyphs/stax_artis_sigma1_64px.gif differ
diff --git a/glyphs/stax_artis_tau1_64px.gif b/glyphs/stax_artis_tau1_64px.gif
new file mode 100644
index 000000000..87b527dae
Binary files /dev/null and b/glyphs/stax_artis_tau1_64px.gif differ
diff --git a/glyphs/stax_astar_64px.gif b/glyphs/stax_astar_64px.gif
new file mode 100644
index 000000000..60fb1e8fc
Binary files /dev/null and b/glyphs/stax_astar_64px.gif differ
diff --git a/glyphs/stax_atheios_64px.gif b/glyphs/stax_atheios_64px.gif
new file mode 100644
index 000000000..051e9c37e
Binary files /dev/null and b/glyphs/stax_atheios_64px.gif differ
diff --git a/glyphs/stax_bsc_64px.gif b/glyphs/stax_bsc_64px.gif
new file mode 100644
index 000000000..956f73dcc
Binary files /dev/null and b/glyphs/stax_bsc_64px.gif differ
diff --git a/glyphs/stax_bttc_64px.gif b/glyphs/stax_bttc_64px.gif
new file mode 100644
index 000000000..99e51ff01
Binary files /dev/null and b/glyphs/stax_bttc_64px.gif differ
diff --git a/glyphs/stax_callisto_64px.gif b/glyphs/stax_callisto_64px.gif
new file mode 100644
index 000000000..44a6b888a
Binary files /dev/null and b/glyphs/stax_callisto_64px.gif differ
diff --git a/glyphs/stax_conflux_espace_64px.gif b/glyphs/stax_conflux_espace_64px.gif
new file mode 100644
index 000000000..d6f790d41
Binary files /dev/null and b/glyphs/stax_conflux_espace_64px.gif differ
diff --git a/glyphs/stax_cube_64px.gif b/glyphs/stax_cube_64px.gif
new file mode 100644
index 000000000..818672285
Binary files /dev/null and b/glyphs/stax_cube_64px.gif differ
diff --git a/glyphs/stax_dexon_64px.gif b/glyphs/stax_dexon_64px.gif
new file mode 100644
index 000000000..d37f6b26b
Binary files /dev/null and b/glyphs/stax_dexon_64px.gif differ
diff --git a/glyphs/stax_ellaism_64px.gif b/glyphs/stax_ellaism_64px.gif
new file mode 100644
index 000000000..b785d4899
Binary files /dev/null and b/glyphs/stax_ellaism_64px.gif differ
diff --git a/glyphs/stax_energywebchain_64px.gif b/glyphs/stax_energywebchain_64px.gif
new file mode 100644
index 000000000..5cd4c4da1
Binary files /dev/null and b/glyphs/stax_energywebchain_64px.gif differ
diff --git a/glyphs/stax_ether1_64px.gif b/glyphs/stax_ether1_64px.gif
new file mode 100644
index 000000000..ec41146ed
Binary files /dev/null and b/glyphs/stax_ether1_64px.gif differ
diff --git a/glyphs/stax_ethereum_64px.gif b/glyphs/stax_ethereum_64px.gif
new file mode 100644
index 000000000..7cd7be3df
Binary files /dev/null and b/glyphs/stax_ethereum_64px.gif differ
diff --git a/glyphs/stax_ethereum_classic_64px.gif b/glyphs/stax_ethereum_classic_64px.gif
new file mode 100644
index 000000000..5aeed55c1
Binary files /dev/null and b/glyphs/stax_ethereum_classic_64px.gif differ
diff --git a/glyphs/stax_ethergem_64px.gif b/glyphs/stax_ethergem_64px.gif
new file mode 100644
index 000000000..8bdb8e5f1
Binary files /dev/null and b/glyphs/stax_ethergem_64px.gif differ
diff --git a/glyphs/stax_ethersocial_64px.gif b/glyphs/stax_ethersocial_64px.gif
new file mode 100644
index 000000000..530fe5540
Binary files /dev/null and b/glyphs/stax_ethersocial_64px.gif differ
diff --git a/glyphs/stax_expanse_64px.gif b/glyphs/stax_expanse_64px.gif
new file mode 100644
index 000000000..61698c8d9
Binary files /dev/null and b/glyphs/stax_expanse_64px.gif differ
diff --git a/glyphs/stax_flare_64px.gif b/glyphs/stax_flare_64px.gif
new file mode 100644
index 000000000..c834fcb36
Binary files /dev/null and b/glyphs/stax_flare_64px.gif differ
diff --git a/glyphs/stax_flare_coston_64px.gif b/glyphs/stax_flare_coston_64px.gif
new file mode 100644
index 000000000..28822f300
Binary files /dev/null and b/glyphs/stax_flare_coston_64px.gif differ
diff --git a/glyphs/stax_gochain_64px.gif b/glyphs/stax_gochain_64px.gif
new file mode 100644
index 000000000..aec56d005
Binary files /dev/null and b/glyphs/stax_gochain_64px.gif differ
diff --git a/glyphs/stax_goerli_64px.gif b/glyphs/stax_goerli_64px.gif
new file mode 100644
index 000000000..3c4839434
Binary files /dev/null and b/glyphs/stax_goerli_64px.gif differ
diff --git a/glyphs/stax_hpb_64px.gif b/glyphs/stax_hpb_64px.gif
new file mode 100644
index 000000000..392151ae6
Binary files /dev/null and b/glyphs/stax_hpb_64px.gif differ
diff --git a/glyphs/stax_id4good_64px.gif b/glyphs/stax_id4good_64px.gif
new file mode 100644
index 000000000..6d04b228f
Binary files /dev/null and b/glyphs/stax_id4good_64px.gif differ
diff --git a/glyphs/stax_kardiachain_64px.gif b/glyphs/stax_kardiachain_64px.gif
new file mode 100644
index 000000000..66b6e6fb9
Binary files /dev/null and b/glyphs/stax_kardiachain_64px.gif differ
diff --git a/glyphs/stax_kusd_64px.gif b/glyphs/stax_kusd_64px.gif
new file mode 100644
index 000000000..b18730662
Binary files /dev/null and b/glyphs/stax_kusd_64px.gif differ
diff --git a/glyphs/stax_meter_64px.gif b/glyphs/stax_meter_64px.gif
new file mode 100644
index 000000000..ee0804bc3
Binary files /dev/null and b/glyphs/stax_meter_64px.gif differ
diff --git a/glyphs/stax_mix_64px.gif b/glyphs/stax_mix_64px.gif
new file mode 100644
index 000000000..e3a3e570a
Binary files /dev/null and b/glyphs/stax_mix_64px.gif differ
diff --git a/glyphs/stax_moonbeam_64px.gif b/glyphs/stax_moonbeam_64px.gif
new file mode 100644
index 000000000..e8485ee55
Binary files /dev/null and b/glyphs/stax_moonbeam_64px.gif differ
diff --git a/glyphs/stax_moonriver_64px.gif b/glyphs/stax_moonriver_64px.gif
new file mode 100644
index 000000000..180985709
Binary files /dev/null and b/glyphs/stax_moonriver_64px.gif differ
diff --git a/glyphs/stax_multivac_64px.gif b/glyphs/stax_multivac_64px.gif
new file mode 100644
index 000000000..e3ea71657
Binary files /dev/null and b/glyphs/stax_multivac_64px.gif differ
diff --git a/glyphs/stax_musicoin_64px.gif b/glyphs/stax_musicoin_64px.gif
new file mode 100644
index 000000000..d9dce6c3f
Binary files /dev/null and b/glyphs/stax_musicoin_64px.gif differ
diff --git a/glyphs/stax_oasys_64px.gif b/glyphs/stax_oasys_64px.gif
new file mode 100644
index 000000000..81c0e5fe8
Binary files /dev/null and b/glyphs/stax_oasys_64px.gif differ
diff --git a/glyphs/stax_okc_64px.gif b/glyphs/stax_okc_64px.gif
new file mode 100644
index 000000000..f377521af
Binary files /dev/null and b/glyphs/stax_okc_64px.gif differ
diff --git a/glyphs/stax_pirl_64px.gif b/glyphs/stax_pirl_64px.gif
new file mode 100644
index 000000000..7c9733164
Binary files /dev/null and b/glyphs/stax_pirl_64px.gif differ
diff --git a/glyphs/stax_poa_64px.gif b/glyphs/stax_poa_64px.gif
new file mode 100644
index 000000000..d857c1781
Binary files /dev/null and b/glyphs/stax_poa_64px.gif differ
diff --git a/glyphs/stax_polygon_64px.gif b/glyphs/stax_polygon_64px.gif
new file mode 100644
index 000000000..40b99e10b
Binary files /dev/null and b/glyphs/stax_polygon_64px.gif differ
diff --git a/glyphs/stax_reosc_64px.gif b/glyphs/stax_reosc_64px.gif
new file mode 100644
index 000000000..fa727e370
Binary files /dev/null and b/glyphs/stax_reosc_64px.gif differ
diff --git a/glyphs/stax_ropsten_64px.gif b/glyphs/stax_ropsten_64px.gif
new file mode 100644
index 000000000..6025affd8
Binary files /dev/null and b/glyphs/stax_ropsten_64px.gif differ
diff --git a/glyphs/stax_rsk_64px.gif b/glyphs/stax_rsk_64px.gif
new file mode 100644
index 000000000..5e25ff6b2
Binary files /dev/null and b/glyphs/stax_rsk_64px.gif differ
diff --git a/glyphs/stax_rsk_testnet_64px.gif b/glyphs/stax_rsk_testnet_64px.gif
new file mode 100644
index 000000000..5e25ff6b2
Binary files /dev/null and b/glyphs/stax_rsk_testnet_64px.gif differ
diff --git a/glyphs/stax_shiden_64px.gif b/glyphs/stax_shiden_64px.gif
new file mode 100644
index 000000000..6bbe136ca
Binary files /dev/null and b/glyphs/stax_shiden_64px.gif differ
diff --git a/glyphs/stax_shyft_64px.gif b/glyphs/stax_shyft_64px.gif
new file mode 100644
index 000000000..78a7ea9c8
Binary files /dev/null and b/glyphs/stax_shyft_64px.gif differ
diff --git a/glyphs/stax_songbird_64px.gif b/glyphs/stax_songbird_64px.gif
new file mode 100644
index 000000000..e635b9569
Binary files /dev/null and b/glyphs/stax_songbird_64px.gif differ
diff --git a/glyphs/stax_tecracoin_64px.gif b/glyphs/stax_tecracoin_64px.gif
new file mode 100644
index 000000000..4fa9b491c
Binary files /dev/null and b/glyphs/stax_tecracoin_64px.gif differ
diff --git a/glyphs/stax_tecratestnet_64px.gif b/glyphs/stax_tecratestnet_64px.gif
new file mode 100644
index 000000000..4fa9b491c
Binary files /dev/null and b/glyphs/stax_tecratestnet_64px.gif differ
diff --git a/glyphs/stax_thundercore_64px.gif b/glyphs/stax_thundercore_64px.gif
new file mode 100644
index 000000000..76134be81
Binary files /dev/null and b/glyphs/stax_thundercore_64px.gif differ
diff --git a/glyphs/stax_tobalaba_64px.gif b/glyphs/stax_tobalaba_64px.gif
new file mode 100644
index 000000000..0125e6b45
Binary files /dev/null and b/glyphs/stax_tobalaba_64px.gif differ
diff --git a/glyphs/stax_tomochain_64px.gif b/glyphs/stax_tomochain_64px.gif
new file mode 100644
index 000000000..6abef3351
Binary files /dev/null and b/glyphs/stax_tomochain_64px.gif differ
diff --git a/glyphs/stax_ubiq_64px.gif b/glyphs/stax_ubiq_64px.gif
new file mode 100644
index 000000000..740b7e99c
Binary files /dev/null and b/glyphs/stax_ubiq_64px.gif differ
diff --git a/glyphs/stax_volta_64px.gif b/glyphs/stax_volta_64px.gif
new file mode 100644
index 000000000..83cfb91c4
Binary files /dev/null and b/glyphs/stax_volta_64px.gif differ
diff --git a/glyphs/stax_wanchain_64px.gif b/glyphs/stax_wanchain_64px.gif
new file mode 100644
index 000000000..27a5582da
Binary files /dev/null and b/glyphs/stax_wanchain_64px.gif differ
diff --git a/glyphs/stax_webchain_64px.gif b/glyphs/stax_webchain_64px.gif
new file mode 100644
index 000000000..585832f1d
Binary files /dev/null and b/glyphs/stax_webchain_64px.gif differ
diff --git a/glyphs/stax_wethio_64px.gif b/glyphs/stax_wethio_64px.gif
new file mode 100644
index 000000000..8a66b1209
Binary files /dev/null and b/glyphs/stax_wethio_64px.gif differ
diff --git a/glyphs/stax_xdcnetwork_64px.gif b/glyphs/stax_xdcnetwork_64px.gif
new file mode 100644
index 000000000..b990ab31e
Binary files /dev/null and b/glyphs/stax_xdcnetwork_64px.gif differ
diff --git a/icons/akroma.png b/icons/akroma.png
deleted file mode 100644
index 22baa92a1..000000000
Binary files a/icons/akroma.png and /dev/null differ
diff --git a/icons/artis_sigma1.png b/icons/artis_sigma1.png
deleted file mode 100644
index f6b47b129..000000000
Binary files a/icons/artis_sigma1.png and /dev/null differ
diff --git a/icons/artis_tau1.png b/icons/artis_tau1.png
deleted file mode 100644
index 388009a32..000000000
Binary files a/icons/artis_tau1.png and /dev/null differ
diff --git a/icons/atheios.png b/icons/atheios.png
deleted file mode 100644
index 22af8d272..000000000
Binary files a/icons/atheios.png and /dev/null differ
diff --git a/icons/blue_app_akroma.gif b/icons/blue_app_akroma.gif
deleted file mode 100644
index 12c9cd215..000000000
Binary files a/icons/blue_app_akroma.gif and /dev/null differ
diff --git a/icons/blue_app_artis_sigma1.gif b/icons/blue_app_artis_sigma1.gif
deleted file mode 100644
index 8c47bf3a5..000000000
Binary files a/icons/blue_app_artis_sigma1.gif and /dev/null differ
diff --git a/icons/blue_app_artis_tau1.gif b/icons/blue_app_artis_tau1.gif
deleted file mode 100644
index 3dfdf0629..000000000
Binary files a/icons/blue_app_artis_tau1.gif and /dev/null differ
diff --git a/icons/blue_app_atheios.gif b/icons/blue_app_atheios.gif
deleted file mode 100644
index 916915645..000000000
Binary files a/icons/blue_app_atheios.gif and /dev/null differ
diff --git a/icons/blue_app_callisto.gif b/icons/blue_app_callisto.gif
deleted file mode 100644
index 162765a35..000000000
Binary files a/icons/blue_app_callisto.gif and /dev/null differ
diff --git a/icons/blue_app_dexon.gif b/icons/blue_app_dexon.gif
deleted file mode 100644
index 3f51c6bc5..000000000
Binary files a/icons/blue_app_dexon.gif and /dev/null differ
diff --git a/icons/blue_app_ellaism.gif b/icons/blue_app_ellaism.gif
deleted file mode 100644
index 0936f88ba..000000000
Binary files a/icons/blue_app_ellaism.gif and /dev/null differ
diff --git a/icons/blue_app_ether1.gif b/icons/blue_app_ether1.gif
deleted file mode 100644
index 1592686a1..000000000
Binary files a/icons/blue_app_ether1.gif and /dev/null differ
diff --git a/icons/blue_app_ethereum.gif b/icons/blue_app_ethereum.gif
deleted file mode 100644
index c3d5c4e1d..000000000
Binary files a/icons/blue_app_ethereum.gif and /dev/null differ
diff --git a/icons/blue_app_ethereum_classic.gif b/icons/blue_app_ethereum_classic.gif
deleted file mode 100644
index dceaa1510..000000000
Binary files a/icons/blue_app_ethereum_classic.gif and /dev/null differ
diff --git a/icons/blue_app_ethergem.gif b/icons/blue_app_ethergem.gif
deleted file mode 100644
index 539f76ebd..000000000
Binary files a/icons/blue_app_ethergem.gif and /dev/null differ
diff --git a/icons/blue_app_ethersocial.gif b/icons/blue_app_ethersocial.gif
deleted file mode 100644
index 2df10f438..000000000
Binary files a/icons/blue_app_ethersocial.gif and /dev/null differ
diff --git a/icons/blue_app_ewc.gif b/icons/blue_app_ewc.gif
deleted file mode 100644
index d1c438fce..000000000
Binary files a/icons/blue_app_ewc.gif and /dev/null differ
diff --git a/icons/blue_app_expanse.gif b/icons/blue_app_expanse.gif
deleted file mode 100644
index 82660042d..000000000
Binary files a/icons/blue_app_expanse.gif and /dev/null differ
diff --git a/icons/blue_app_gochain.gif b/icons/blue_app_gochain.gif
deleted file mode 100644
index 50ae2bee9..000000000
Binary files a/icons/blue_app_gochain.gif and /dev/null differ
diff --git a/icons/blue_app_goerli.gif b/icons/blue_app_goerli.gif
deleted file mode 100644
index c3d5c4e1d..000000000
Binary files a/icons/blue_app_goerli.gif and /dev/null differ
diff --git a/icons/blue_app_hpb.gif b/icons/blue_app_hpb.gif
deleted file mode 100644
index d15b589b0..000000000
Binary files a/icons/blue_app_hpb.gif and /dev/null differ
diff --git a/icons/blue_app_kusd.gif b/icons/blue_app_kusd.gif
deleted file mode 100644
index d4c5496a1..000000000
Binary files a/icons/blue_app_kusd.gif and /dev/null differ
diff --git a/icons/blue_app_mix.gif b/icons/blue_app_mix.gif
deleted file mode 100644
index 38cdca838..000000000
Binary files a/icons/blue_app_mix.gif and /dev/null differ
diff --git a/icons/blue_app_musicoin.gif b/icons/blue_app_musicoin.gif
deleted file mode 100644
index 42f818510..000000000
Binary files a/icons/blue_app_musicoin.gif and /dev/null differ
diff --git a/icons/blue_app_pirl.gif b/icons/blue_app_pirl.gif
deleted file mode 100644
index a6824ae7d..000000000
Binary files a/icons/blue_app_pirl.gif and /dev/null differ
diff --git a/icons/blue_app_poa.gif b/icons/blue_app_poa.gif
deleted file mode 100644
index 679fc6661..000000000
Binary files a/icons/blue_app_poa.gif and /dev/null differ
diff --git a/icons/blue_app_reosc.gif b/icons/blue_app_reosc.gif
deleted file mode 100644
index aaf46981d..000000000
Binary files a/icons/blue_app_reosc.gif and /dev/null differ
diff --git a/icons/blue_app_ropsten.gif b/icons/blue_app_ropsten.gif
deleted file mode 100644
index c3d5c4e1d..000000000
Binary files a/icons/blue_app_ropsten.gif and /dev/null differ
diff --git a/icons/blue_app_rsk.gif b/icons/blue_app_rsk.gif
deleted file mode 100644
index 7cd4fa050..000000000
Binary files a/icons/blue_app_rsk.gif and /dev/null differ
diff --git a/icons/blue_app_rsk_testnet.gif b/icons/blue_app_rsk_testnet.gif
deleted file mode 100644
index 2fd05e6b7..000000000
Binary files a/icons/blue_app_rsk_testnet.gif and /dev/null differ
diff --git a/icons/blue_app_theta.gif b/icons/blue_app_theta.gif
deleted file mode 100644
index 5056f1b45..000000000
Binary files a/icons/blue_app_theta.gif and /dev/null differ
diff --git a/icons/blue_app_thundercore.gif b/icons/blue_app_thundercore.gif
deleted file mode 100644
index bfa6ba571..000000000
Binary files a/icons/blue_app_thundercore.gif and /dev/null differ
diff --git a/icons/blue_app_tobalaba.gif b/icons/blue_app_tobalaba.gif
deleted file mode 100644
index d1c438fce..000000000
Binary files a/icons/blue_app_tobalaba.gif and /dev/null differ
diff --git a/icons/blue_app_tomochain.gif b/icons/blue_app_tomochain.gif
deleted file mode 100644
index 6ef28c768..000000000
Binary files a/icons/blue_app_tomochain.gif and /dev/null differ
diff --git a/icons/blue_app_ubiq.gif b/icons/blue_app_ubiq.gif
deleted file mode 100644
index 6ac116acf..000000000
Binary files a/icons/blue_app_ubiq.gif and /dev/null differ
diff --git a/icons/blue_app_volta.gif b/icons/blue_app_volta.gif
deleted file mode 100644
index d1c438fce..000000000
Binary files a/icons/blue_app_volta.gif and /dev/null differ
diff --git a/icons/blue_app_wanchain.gif b/icons/blue_app_wanchain.gif
deleted file mode 100644
index 0332113a8..000000000
Binary files a/icons/blue_app_wanchain.gif and /dev/null differ
diff --git a/icons/blue_app_webchain.gif b/icons/blue_app_webchain.gif
deleted file mode 100644
index 50c5b1f99..000000000
Binary files a/icons/blue_app_webchain.gif and /dev/null differ
diff --git a/icons/blue_badge_thundercore.gif b/icons/blue_badge_thundercore.gif
deleted file mode 100644
index a31bbe32d..000000000
Binary files a/icons/blue_badge_thundercore.gif and /dev/null differ
diff --git a/icons/blue_badge_tomochain.gif b/icons/blue_badge_tomochain.gif
deleted file mode 100644
index cf7c4b568..000000000
Binary files a/icons/blue_badge_tomochain.gif and /dev/null differ
diff --git a/icons/callisto.png b/icons/callisto.png
deleted file mode 100644
index 3319589e7..000000000
Binary files a/icons/callisto.png and /dev/null differ
diff --git a/icons/dexon.png b/icons/dexon.png
deleted file mode 100644
index c6a934a8f..000000000
Binary files a/icons/dexon.png and /dev/null differ
diff --git a/icons/ellaism.png b/icons/ellaism.png
deleted file mode 100644
index 9ea64d0bd..000000000
Binary files a/icons/ellaism.png and /dev/null differ
diff --git a/icons/ether1.png b/icons/ether1.png
deleted file mode 100644
index 68aec970e..000000000
Binary files a/icons/ether1.png and /dev/null differ
diff --git a/icons/ethereum.png b/icons/ethereum.png
deleted file mode 100755
index 60e111ce0..000000000
Binary files a/icons/ethereum.png and /dev/null differ
diff --git a/icons/ethereum_classic.png b/icons/ethereum_classic.png
deleted file mode 100755
index 6807e1493..000000000
Binary files a/icons/ethereum_classic.png and /dev/null differ
diff --git a/icons/ethergem.png b/icons/ethergem.png
deleted file mode 100644
index ad9608503..000000000
Binary files a/icons/ethergem.png and /dev/null differ
diff --git a/icons/ethersocial.png b/icons/ethersocial.png
deleted file mode 100644
index 5fd623f3f..000000000
Binary files a/icons/ethersocial.png and /dev/null differ
diff --git a/icons/ewc.png b/icons/ewc.png
deleted file mode 100644
index 5bda6b796..000000000
Binary files a/icons/ewc.png and /dev/null differ
diff --git a/icons/expanse.png b/icons/expanse.png
deleted file mode 100755
index 27f275cc3..000000000
Binary files a/icons/expanse.png and /dev/null differ
diff --git a/icons/flare.png b/icons/flare.png
deleted file mode 100644
index 57d5519e6..000000000
Binary files a/icons/flare.png and /dev/null differ
diff --git a/icons/flare_coston.png b/icons/flare_coston.png
deleted file mode 100644
index b732549b2..000000000
Binary files a/icons/flare_coston.png and /dev/null differ
diff --git a/icons/gochain.png b/icons/gochain.png
deleted file mode 100644
index 67154f805..000000000
Binary files a/icons/gochain.png and /dev/null differ
diff --git a/icons/goerli.png b/icons/goerli.png
deleted file mode 100755
index 60e111ce0..000000000
Binary files a/icons/goerli.png and /dev/null differ
diff --git a/icons/hpb.png b/icons/hpb.png
deleted file mode 100644
index 39d1d419d..000000000
Binary files a/icons/hpb.png and /dev/null differ
diff --git a/icons/icon_split.gif b/icons/icon_split.gif
deleted file mode 100644
index 0ab40011f..000000000
Binary files a/icons/icon_split.gif and /dev/null differ
diff --git a/icons/kusd.png b/icons/kusd.png
deleted file mode 100644
index e69b3fc3a..000000000
Binary files a/icons/kusd.png and /dev/null differ
diff --git a/icons/mix.png b/icons/mix.png
deleted file mode 100644
index 02af27ecf..000000000
Binary files a/icons/mix.png and /dev/null differ
diff --git a/icons/musicoin.png b/icons/musicoin.png
deleted file mode 100644
index 2d6ec90d1..000000000
Binary files a/icons/musicoin.png and /dev/null differ
diff --git a/icons/nanos_app_tecracoin.gif b/icons/nanos_app_tecracoin.gif
old mode 100755
new mode 100644
diff --git a/icons/nanos_app_tecratestnet.gif b/icons/nanos_app_tecratestnet.gif
old mode 100755
new mode 100644
diff --git a/icons/nanox_app_tecracoin.gif b/icons/nanox_app_tecracoin.gif
old mode 100755
new mode 100644
diff --git a/icons/nanox_app_tecratestnet.gif b/icons/nanox_app_tecratestnet.gif
old mode 100755
new mode 100644
diff --git a/icons/pirl.png b/icons/pirl.png
deleted file mode 100644
index 9ba9202fc..000000000
Binary files a/icons/pirl.png and /dev/null differ
diff --git a/icons/poa.png b/icons/poa.png
deleted file mode 100644
index 1443ae071..000000000
Binary files a/icons/poa.png and /dev/null differ
diff --git a/icons/reosc.png b/icons/reosc.png
deleted file mode 100644
index c38bbc324..000000000
Binary files a/icons/reosc.png and /dev/null differ
diff --git a/icons/ropsten.png b/icons/ropsten.png
deleted file mode 100755
index 60e111ce0..000000000
Binary files a/icons/ropsten.png and /dev/null differ
diff --git a/icons/rsk.png b/icons/rsk.png
deleted file mode 100644
index 2e8a9b4dd..000000000
Binary files a/icons/rsk.png and /dev/null differ
diff --git a/icons/rsk_testnet.png b/icons/rsk_testnet.png
deleted file mode 100644
index c69449b2b..000000000
Binary files a/icons/rsk_testnet.png and /dev/null differ
diff --git a/icons/songbird.png b/icons/songbird.png
deleted file mode 100644
index 0fd35ec03..000000000
Binary files a/icons/songbird.png and /dev/null differ
diff --git a/icons/stax_app_akroma.gif b/icons/stax_app_akroma.gif
new file mode 100644
index 000000000..79768660e
Binary files /dev/null and b/icons/stax_app_akroma.gif differ
diff --git a/icons/stax_app_apothemnetwork.gif b/icons/stax_app_apothemnetwork.gif
new file mode 100644
index 000000000..381f07069
Binary files /dev/null and b/icons/stax_app_apothemnetwork.gif differ
diff --git a/icons/stax_app_artis_sigma1.gif b/icons/stax_app_artis_sigma1.gif
new file mode 100644
index 000000000..8d769dba2
Binary files /dev/null and b/icons/stax_app_artis_sigma1.gif differ
diff --git a/icons/stax_app_artis_tau1.gif b/icons/stax_app_artis_tau1.gif
new file mode 100644
index 000000000..555be4a6d
Binary files /dev/null and b/icons/stax_app_artis_tau1.gif differ
diff --git a/icons/stax_app_astar.gif b/icons/stax_app_astar.gif
new file mode 100644
index 000000000..458e51910
Binary files /dev/null and b/icons/stax_app_astar.gif differ
diff --git a/icons/stax_app_atheios.gif b/icons/stax_app_atheios.gif
new file mode 100644
index 000000000..10a3e3b3b
Binary files /dev/null and b/icons/stax_app_atheios.gif differ
diff --git a/icons/stax_app_bsc.gif b/icons/stax_app_bsc.gif
new file mode 100644
index 000000000..311d31a04
Binary files /dev/null and b/icons/stax_app_bsc.gif differ
diff --git a/icons/stax_app_bttc.gif b/icons/stax_app_bttc.gif
new file mode 100644
index 000000000..cc8a3f986
Binary files /dev/null and b/icons/stax_app_bttc.gif differ
diff --git a/icons/stax_app_callisto.gif b/icons/stax_app_callisto.gif
new file mode 100644
index 000000000..890dd9f34
Binary files /dev/null and b/icons/stax_app_callisto.gif differ
diff --git a/icons/stax_app_conflux_espace.gif b/icons/stax_app_conflux_espace.gif
new file mode 100644
index 000000000..e39f4425b
Binary files /dev/null and b/icons/stax_app_conflux_espace.gif differ
diff --git a/icons/stax_app_cube.gif b/icons/stax_app_cube.gif
new file mode 100644
index 000000000..1a5b3c8e6
Binary files /dev/null and b/icons/stax_app_cube.gif differ
diff --git a/icons/stax_app_dexon.gif b/icons/stax_app_dexon.gif
new file mode 100644
index 000000000..692537fdd
Binary files /dev/null and b/icons/stax_app_dexon.gif differ
diff --git a/icons/stax_app_ellaism.gif b/icons/stax_app_ellaism.gif
new file mode 100644
index 000000000..ac5ef8500
Binary files /dev/null and b/icons/stax_app_ellaism.gif differ
diff --git a/icons/stax_app_energywebchain.gif b/icons/stax_app_energywebchain.gif
new file mode 100644
index 000000000..3f8a57438
Binary files /dev/null and b/icons/stax_app_energywebchain.gif differ
diff --git a/icons/stax_app_ether1.gif b/icons/stax_app_ether1.gif
new file mode 100644
index 000000000..1f4698843
Binary files /dev/null and b/icons/stax_app_ether1.gif differ
diff --git a/icons/stax_app_ethereum.gif b/icons/stax_app_ethereum.gif
new file mode 100644
index 000000000..c1d6d3401
Binary files /dev/null and b/icons/stax_app_ethereum.gif differ
diff --git a/icons/stax_app_ethereum_classic.gif b/icons/stax_app_ethereum_classic.gif
new file mode 100644
index 000000000..10a661d87
Binary files /dev/null and b/icons/stax_app_ethereum_classic.gif differ
diff --git a/icons/stax_app_ethergem.gif b/icons/stax_app_ethergem.gif
new file mode 100644
index 000000000..0ed7b1cf9
Binary files /dev/null and b/icons/stax_app_ethergem.gif differ
diff --git a/icons/stax_app_ethersocial.gif b/icons/stax_app_ethersocial.gif
new file mode 100644
index 000000000..e8fc4dd4a
Binary files /dev/null and b/icons/stax_app_ethersocial.gif differ
diff --git a/icons/stax_app_expanse.gif b/icons/stax_app_expanse.gif
new file mode 100644
index 000000000..9dfd8705f
Binary files /dev/null and b/icons/stax_app_expanse.gif differ
diff --git a/icons/stax_app_flare.gif b/icons/stax_app_flare.gif
new file mode 100644
index 000000000..4d1a0f875
Binary files /dev/null and b/icons/stax_app_flare.gif differ
diff --git a/icons/stax_app_flare_coston.gif b/icons/stax_app_flare_coston.gif
new file mode 100644
index 000000000..2f77deea1
Binary files /dev/null and b/icons/stax_app_flare_coston.gif differ
diff --git a/icons/stax_app_gochain.gif b/icons/stax_app_gochain.gif
new file mode 100644
index 000000000..04bb08df6
Binary files /dev/null and b/icons/stax_app_gochain.gif differ
diff --git a/icons/stax_app_goerli.gif b/icons/stax_app_goerli.gif
new file mode 100644
index 000000000..95c819d26
Binary files /dev/null and b/icons/stax_app_goerli.gif differ
diff --git a/icons/stax_app_hpb.gif b/icons/stax_app_hpb.gif
new file mode 100644
index 000000000..4c4e50d16
Binary files /dev/null and b/icons/stax_app_hpb.gif differ
diff --git a/icons/stax_app_id4good.gif b/icons/stax_app_id4good.gif
new file mode 100644
index 000000000..ae3fae4a7
Binary files /dev/null and b/icons/stax_app_id4good.gif differ
diff --git a/icons/stax_app_kardiachain.gif b/icons/stax_app_kardiachain.gif
new file mode 100644
index 000000000..0c092ffa2
Binary files /dev/null and b/icons/stax_app_kardiachain.gif differ
diff --git a/icons/stax_app_kusd.gif b/icons/stax_app_kusd.gif
new file mode 100644
index 000000000..18b1a1c5e
Binary files /dev/null and b/icons/stax_app_kusd.gif differ
diff --git a/icons/stax_app_meter.gif b/icons/stax_app_meter.gif
new file mode 100644
index 000000000..d07813d1a
Binary files /dev/null and b/icons/stax_app_meter.gif differ
diff --git a/icons/stax_app_mix.gif b/icons/stax_app_mix.gif
new file mode 100644
index 000000000..f82aafcb9
Binary files /dev/null and b/icons/stax_app_mix.gif differ
diff --git a/icons/stax_app_moonbeam.gif b/icons/stax_app_moonbeam.gif
new file mode 100644
index 000000000..c8d2c9b0b
Binary files /dev/null and b/icons/stax_app_moonbeam.gif differ
diff --git a/icons/stax_app_moonriver.gif b/icons/stax_app_moonriver.gif
new file mode 100644
index 000000000..69466a7a5
Binary files /dev/null and b/icons/stax_app_moonriver.gif differ
diff --git a/icons/stax_app_multivac.gif b/icons/stax_app_multivac.gif
new file mode 100644
index 000000000..ad33059e7
Binary files /dev/null and b/icons/stax_app_multivac.gif differ
diff --git a/icons/stax_app_musicoin.gif b/icons/stax_app_musicoin.gif
new file mode 100644
index 000000000..eced2ed72
Binary files /dev/null and b/icons/stax_app_musicoin.gif differ
diff --git a/icons/stax_app_oasys.gif b/icons/stax_app_oasys.gif
new file mode 100644
index 000000000..83995c697
Binary files /dev/null and b/icons/stax_app_oasys.gif differ
diff --git a/icons/stax_app_okc.gif b/icons/stax_app_okc.gif
new file mode 100644
index 000000000..38cfa3cc3
Binary files /dev/null and b/icons/stax_app_okc.gif differ
diff --git a/icons/stax_app_pirl.gif b/icons/stax_app_pirl.gif
new file mode 100644
index 000000000..6ac7154d3
Binary files /dev/null and b/icons/stax_app_pirl.gif differ
diff --git a/icons/stax_app_poa.gif b/icons/stax_app_poa.gif
new file mode 100644
index 000000000..afa1186ba
Binary files /dev/null and b/icons/stax_app_poa.gif differ
diff --git a/icons/stax_app_polygon.gif b/icons/stax_app_polygon.gif
new file mode 100644
index 000000000..eba2eaad3
Binary files /dev/null and b/icons/stax_app_polygon.gif differ
diff --git a/icons/stax_app_reosc.gif b/icons/stax_app_reosc.gif
new file mode 100644
index 000000000..50fe3fba6
Binary files /dev/null and b/icons/stax_app_reosc.gif differ
diff --git a/icons/stax_app_ropsten.gif b/icons/stax_app_ropsten.gif
new file mode 100644
index 000000000..4c7a5a0e7
Binary files /dev/null and b/icons/stax_app_ropsten.gif differ
diff --git a/icons/stax_app_rsk.gif b/icons/stax_app_rsk.gif
new file mode 100644
index 000000000..a576134bc
Binary files /dev/null and b/icons/stax_app_rsk.gif differ
diff --git a/icons/stax_app_rsk_testnet.gif b/icons/stax_app_rsk_testnet.gif
new file mode 100644
index 000000000..a576134bc
Binary files /dev/null and b/icons/stax_app_rsk_testnet.gif differ
diff --git a/icons/stax_app_shiden.gif b/icons/stax_app_shiden.gif
new file mode 100644
index 000000000..132230948
Binary files /dev/null and b/icons/stax_app_shiden.gif differ
diff --git a/icons/stax_app_shyft.gif b/icons/stax_app_shyft.gif
new file mode 100644
index 000000000..0741eddac
Binary files /dev/null and b/icons/stax_app_shyft.gif differ
diff --git a/icons/stax_app_songbird.gif b/icons/stax_app_songbird.gif
new file mode 100644
index 000000000..811d72ac1
Binary files /dev/null and b/icons/stax_app_songbird.gif differ
diff --git a/icons/stax_app_tecracoin.gif b/icons/stax_app_tecracoin.gif
new file mode 100644
index 000000000..a1ccb2d47
Binary files /dev/null and b/icons/stax_app_tecracoin.gif differ
diff --git a/icons/stax_app_tecratestnet.gif b/icons/stax_app_tecratestnet.gif
new file mode 100644
index 000000000..a1ccb2d47
Binary files /dev/null and b/icons/stax_app_tecratestnet.gif differ
diff --git a/icons/stax_app_thundercore.gif b/icons/stax_app_thundercore.gif
new file mode 100644
index 000000000..4d730a167
Binary files /dev/null and b/icons/stax_app_thundercore.gif differ
diff --git a/icons/stax_app_tobalaba.gif b/icons/stax_app_tobalaba.gif
new file mode 100644
index 000000000..cd3e9464e
Binary files /dev/null and b/icons/stax_app_tobalaba.gif differ
diff --git a/icons/stax_app_tomochain.gif b/icons/stax_app_tomochain.gif
new file mode 100644
index 000000000..eb8d01a1a
Binary files /dev/null and b/icons/stax_app_tomochain.gif differ
diff --git a/icons/stax_app_ubiq.gif b/icons/stax_app_ubiq.gif
new file mode 100644
index 000000000..afd0577ad
Binary files /dev/null and b/icons/stax_app_ubiq.gif differ
diff --git a/icons/stax_app_volta.gif b/icons/stax_app_volta.gif
new file mode 100644
index 000000000..ea4c02447
Binary files /dev/null and b/icons/stax_app_volta.gif differ
diff --git a/icons/stax_app_wanchain.gif b/icons/stax_app_wanchain.gif
new file mode 100644
index 000000000..cf628048c
Binary files /dev/null and b/icons/stax_app_wanchain.gif differ
diff --git a/icons/stax_app_webchain.gif b/icons/stax_app_webchain.gif
new file mode 100644
index 000000000..3deecb3ff
Binary files /dev/null and b/icons/stax_app_webchain.gif differ
diff --git a/icons/stax_app_wethio.gif b/icons/stax_app_wethio.gif
new file mode 100644
index 000000000..4b540302e
Binary files /dev/null and b/icons/stax_app_wethio.gif differ
diff --git a/icons/stax_app_xdcnetwork.gif b/icons/stax_app_xdcnetwork.gif
new file mode 100644
index 000000000..2cd15b212
Binary files /dev/null and b/icons/stax_app_xdcnetwork.gif differ
diff --git a/icons/thundercore.png b/icons/thundercore.png
deleted file mode 100644
index 49758acfc..000000000
Binary files a/icons/thundercore.png and /dev/null differ
diff --git a/icons/tobalaba.png b/icons/tobalaba.png
deleted file mode 100644
index 5bda6b796..000000000
Binary files a/icons/tobalaba.png and /dev/null differ
diff --git a/icons/tomochain.png b/icons/tomochain.png
deleted file mode 100644
index 9e20e2c34..000000000
Binary files a/icons/tomochain.png and /dev/null differ
diff --git a/icons/ubiq.png b/icons/ubiq.png
deleted file mode 100755
index b702a7b28..000000000
Binary files a/icons/ubiq.png and /dev/null differ
diff --git a/icons/volta.png b/icons/volta.png
deleted file mode 100644
index 5bda6b796..000000000
Binary files a/icons/volta.png and /dev/null differ
diff --git a/icons/wanchain.png b/icons/wanchain.png
deleted file mode 100755
index a73f62bb8..000000000
Binary files a/icons/wanchain.png and /dev/null differ
diff --git a/icons/webchain.png b/icons/webchain.png
deleted file mode 100644
index be97f3cec..000000000
Binary files a/icons/webchain.png and /dev/null differ
diff --git a/src/common_ui.h b/src/common_ui.h
index 9b2b0dc88..e14f57baf 100644
--- a/src/common_ui.h
+++ b/src/common_ui.h
@@ -9,7 +9,6 @@ void ui_display_public_eth2(void);
void ui_display_privacy_public_key(void);
void ui_display_privacy_shared_secret(void);
void ui_display_public_key(void);
-void ui_display_sign(void);
void ui_sign_712_v0(void);
void ui_display_stark_public(void);
void ui_confirm_selector(void);
diff --git a/src/eth_plugin_handler.c b/src/eth_plugin_handler.c
index 3aa6883ef..bb73e9e1f 100644
--- a/src/eth_plugin_handler.c
+++ b/src/eth_plugin_handler.c
@@ -47,6 +47,8 @@ void eth_plugin_prepare_query_contract_UI(ethQueryContractUI_t *queryContractUI,
uint32_t titleLength,
char *msg,
uint32_t msgLength) {
+ uint64_t chain_id;
+
memset((uint8_t *) queryContractUI, 0, sizeof(ethQueryContractUI_t));
// If no extra information was found, set the pointer to NULL
@@ -64,7 +66,8 @@ void eth_plugin_prepare_query_contract_UI(ethQueryContractUI_t *queryContractUI,
}
queryContractUI->screenIndex = screenIndex;
- strlcpy(queryContractUI->network_ticker, get_network_ticker(), MAX_TICKER_LEN);
+ chain_id = get_tx_chain_id();
+ strlcpy(queryContractUI->network_ticker, get_displayable_ticker(&chain_id), MAX_TICKER_LEN);
queryContractUI->title = title;
queryContractUI->titleLength = titleLength;
queryContractUI->msg = msg;
@@ -149,7 +152,7 @@ eth_plugin_result_t eth_plugin_perform_init(uint8_t *contractAddress,
}
// Do not handle a plugin if running in swap mode
- if (called_from_swap && (contractAddress != NULL)) {
+ if (G_called_from_swap && (contractAddress != NULL)) {
PRINTF("eth_plug_init aborted in swap mode\n");
return 0;
}
diff --git a/src/eth_plugin_internal.h b/src/eth_plugin_internal.h
index 692c9b609..2d2ca0369 100644
--- a/src/eth_plugin_internal.h
+++ b/src/eth_plugin_internal.h
@@ -7,7 +7,6 @@
#define SELECTOR_SIZE 4
#define PARAMETER_LENGTH 32
-#define RUN_APPLICATION 1
void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size);
diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c
index 75e4d3a8e..604b8a26c 100644
--- a/src/handle_swap_sign_transaction.c
+++ b/src/handle_swap_sign_transaction.c
@@ -1,8 +1,15 @@
#include "os_io_seproxyhal.h"
+#include "os.h"
#include "ux.h"
#include "handle_swap_sign_transaction.h"
#include "shared_context.h"
#include "utils.h"
+#ifdef HAVE_NBGL
+#include "nbgl_use_case.h"
+#endif // HAVE_NBGL
+
+// Save the BSS address where we will write the return value when finished
+static uint8_t* G_swap_sign_return_value_address;
bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params,
chain_config_t* config) {
@@ -45,14 +52,30 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti
stack_data.maxFee,
sizeof(stack_data.maxFee));
+ // Full reset the global variables
+ os_explicit_zero_BSS_segment();
+ // Keep the address at which we'll reply the signing status
+ G_swap_sign_return_value_address = &sign_transaction_params->result;
+ // Commit the values read from exchange to the clean global space
+
memcpy(&strings.common, &stack_data, sizeof(stack_data));
return true;
}
+void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success) {
+ *G_swap_sign_return_value_address = is_success;
+ os_lib_end();
+}
+
void handle_swap_sign_transaction(chain_config_t* config) {
+ UX_INIT();
+#ifdef HAVE_NBGL
+ nbgl_useCaseSpinner("Signing");
+#endif // HAVE_NBGL
+
chainConfig = config;
reset_app_context();
- called_from_swap = true;
+ G_called_from_swap = true;
io_seproxyhal_init();
if (N_storage.initialized != 0x01) {
@@ -65,18 +88,15 @@ void handle_swap_sign_transaction(chain_config_t* config) {
nvm_write((void*) &N_storage, (void*) &storage, sizeof(internalStorage_t));
}
- UX_INIT();
USB_power(0);
USB_power(1);
// ui_idle();
PRINTF("USB power ON/OFF\n");
-#ifdef TARGET_NANOX
+#ifdef HAVE_BLE
// grab the current plane mode setting
G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0);
-#endif // TARGET_NANOX
-#ifdef HAVE_BLE
BLE_power(0, NULL);
- BLE_power(1, "Nano X");
+ BLE_power(1, NULL);
#endif // HAVE_BLE
app_main();
}
diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h
index 21b52c356..d34a6d860 100644
--- a/src/handle_swap_sign_transaction.h
+++ b/src/handle_swap_sign_transaction.h
@@ -1,5 +1,4 @@
-#ifndef _HANDLE_SWAP_SIGN_TRANSACTION_H_
-#define _HANDLE_SWAP_SIGN_TRANSACTION_H_
+#pragma once
#include "swap_lib_calls.h"
#include "chainConfig.h"
@@ -9,4 +8,4 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti
void handle_swap_sign_transaction(chain_config_t* config);
-#endif // _HANDLE_SWAP_SIGN_TRANSACTION_H_
\ No newline at end of file
+void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success);
diff --git a/src/main.c b/src/main.c
index a483bf401..3399b8614 100644
--- a/src/main.c
+++ b/src/main.c
@@ -52,7 +52,7 @@ cx_sha3_t global_sha3;
uint8_t appState;
uint16_t apdu_response_code;
-bool called_from_swap;
+bool G_called_from_swap;
pluginType_t pluginType;
#ifdef HAVE_STARKWARE
bool quantumSet;
@@ -69,12 +69,15 @@ bolos_ux_params_t G_ux_params;
const internalStorage_t N_storage_real;
-chain_config_t *chainConfig;
+#ifdef HAVE_NBGL
+caller_app_t *caller_app = NULL;
+#endif
+chain_config_t *chainConfig = NULL;
void reset_app_context() {
// PRINTF("!!RESET_APP_CONTEXT\n");
appState = APP_STATE_IDLE;
- called_from_swap = false;
+ G_called_from_swap = false;
pluginType = OLD_INTERNAL;
#ifdef HAVE_STARKWARE
quantumSet = false;
@@ -877,9 +880,11 @@ 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);
}
+#endif
unsigned char io_event(__attribute__((unused)) unsigned char channel) {
// nothing done with the event, throw an error on the transport layer if
@@ -890,10 +895,11 @@ unsigned char io_event(__attribute__((unused)) unsigned char channel) {
case SEPROXYHAL_TAG_FINGER_EVENT:
UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer);
break;
-
+#ifdef HAVE_BAGL
case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT:
UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer);
break;
+#endif // HAVE_BAGL
case SEPROXYHAL_TAG_STATUS_EVENT:
if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID &&
@@ -901,22 +907,23 @@ unsigned char io_event(__attribute__((unused)) unsigned char channel) {
SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) {
THROW(EXCEPTION_IO_RESET);
}
- // no break is intentional
+ __attribute__((fallthrough));
default:
UX_DEFAULT_EVENT();
break;
case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT:
+#ifdef HAVE_BAGL
UX_DISPLAYED_EVENT({});
+#endif // HAVE_BAGL
+#ifdef HAVE_NBGL
+ UX_DEFAULT_EVENT();
+#endif // HAVE_NBGL
break;
-#if 0
- case SEPROXYHAL_TAG_TICKER_EVENT:
- UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer,
- {
- });
- break;
-#endif
+ case SEPROXYHAL_TAG_TICKER_EVENT:
+ UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {});
+ break;
}
// close the event if not done previously (by a display or whatever)
@@ -946,14 +953,27 @@ void init_coin_config(chain_config_t *coin_config) {
coin_config->kind = CHAIN_KIND;
}
-void coin_main(chain_config_t *coin_config) {
+void coin_main(libargs_t *args) {
chain_config_t config;
- if (coin_config == NULL) {
+ if (args) {
+ if (args->chain_config != NULL) {
+ chainConfig = args->chain_config;
+ }
+#ifdef HAVE_NBGL
+ if ((caller_app = args->caller_app) != NULL) {
+ if (chainConfig != NULL) {
+ caller_app->type = CALLER_TYPE_CLONE;
+ } else {
+ caller_app->type = CALLER_TYPE_PLUGIN;
+ }
+ }
+#endif
+ }
+ if (chainConfig == NULL) {
init_coin_config(&config);
chainConfig = &config;
- } else {
- chainConfig = coin_config;
}
+
reset_app_context();
tmpCtx.transactionContext.currentItemIndex = 0;
@@ -964,10 +984,10 @@ void coin_main(chain_config_t *coin_config) {
TRY {
io_seproxyhal_init();
-#ifdef TARGET_NANOX
+#ifdef HAVE_BLE
// grab the current plane mode setting
G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0);
-#endif // TARGET_NANOX
+#endif // HAVE_BLE
if (!N_storage.initialized) {
internalStorage_t storage;
@@ -995,7 +1015,7 @@ void coin_main(chain_config_t *coin_config) {
#ifdef HAVE_BLE
BLE_power(0, NULL);
- BLE_power(1, "Nano X");
+ BLE_power(1, NULL);
#endif // HAVE_BLE
#ifdef HAVE_DOMAIN_NAME
@@ -1022,18 +1042,7 @@ void coin_main(chain_config_t *coin_config) {
app_exit();
}
-struct libargs_s {
- unsigned int id;
- unsigned int command;
- chain_config_t *chain_config;
- union {
- check_address_parameters_t *check_address;
- create_transaction_parameters_t *create_transaction;
- get_printable_amount_parameters_t *get_printable_amount;
- };
-};
-
-static void library_main_helper(struct libargs_s *args) {
+static void library_main_helper(libargs_t *args) {
check_api_level(CX_COMPAT_APILEVEL);
PRINTF("Inside a library \n");
switch (args->command) {
@@ -1061,13 +1070,13 @@ static void library_main_helper(struct libargs_s *args) {
}
}
-void library_main(struct libargs_s *args) {
+void library_main(libargs_t *args) {
chain_config_t coin_config;
if (args->chain_config == NULL) {
init_coin_config(&coin_config);
args->chain_config = &coin_config;
}
- bool end = false;
+ volatile bool end = false;
/* This loop ensures that library_main_helper and os_lib_end are called
* within a try context, even if an exception is thrown */
while (1) {
@@ -1093,6 +1102,7 @@ __attribute__((section(".boot"))) int main(int arg0) {
unsigned int libcall_params[5];
chain_config_t local_chainConfig;
init_coin_config(&local_chainConfig);
+
PRINTF("Hello from Eth-clone\n");
check_api_level(CX_COMPAT_APILEVEL);
// delegate to Ethereum app/lib
@@ -1100,7 +1110,22 @@ __attribute__((section(".boot"))) int main(int arg0) {
libcall_params[1] = 0x100;
libcall_params[2] = RUN_APPLICATION;
libcall_params[3] = (unsigned int) &local_chainConfig;
- libcall_params[4] = 0;
+#ifdef HAVE_NBGL
+ const char app_name[] = APPNAME;
+ caller_app_t capp;
+ 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 = app_name;
+ capp.icon = &icon_details;
+ libcall_params[4] = (unsigned int) &capp;
+#else
+ libcall_params[4] = NULL;
+#endif // HAVE_NBGL
+
if (arg0) {
// call as a library
libcall_params[2] = ((unsigned int *) arg0)[1];
@@ -1132,7 +1157,7 @@ __attribute__((section(".boot"))) int main(int arg0) {
return 0;
}
- struct libargs_s *args = (struct libargs_s *) arg0;
+ libargs_t *args = (libargs_t *) arg0;
if (args->id != 0x100) {
app_exit();
return 0;
@@ -1140,7 +1165,7 @@ __attribute__((section(".boot"))) int main(int arg0) {
switch (args->command) {
case RUN_APPLICATION:
// called as ethereum from altcoin or plugin
- coin_main(args->chain_config);
+ coin_main(args);
break;
default:
// called as ethereum or altcoin library
diff --git a/src/shared_context.h b/src/shared_context.h
index ce907ddd9..f83320cb5 100644
--- a/src/shared_context.h
+++ b/src/shared_context.h
@@ -7,6 +7,9 @@
#include "tokens.h"
#include "chainConfig.h"
#include "nft.h"
+#ifdef HAVE_NBGL
+#include "nbgl_types.h"
+#endif
#define MAX_BIP32_PATH 10
@@ -210,7 +213,7 @@ extern strings_t strings;
extern cx_sha3_t global_sha3;
extern const internalStorage_t N_storage_real;
-extern bool called_from_swap;
+extern bool G_called_from_swap;
typedef enum {
EXTERNAL, // External plugin, set by setExternalPlugin.
@@ -221,6 +224,16 @@ typedef enum {
extern pluginType_t pluginType;
+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 uint8_t appState;
#ifdef HAVE_STARKWARE
extern bool quantumSet;
@@ -229,6 +242,8 @@ extern bool quantumSet;
extern uint32_t eth2WithdrawalIndex;
#endif
+extern caller_app_t *caller_app;
+
void reset_app_context(void);
const uint8_t *parseBip32(const uint8_t *dataBuffer, uint8_t *dataLength, bip32_path_t *bip32);
diff --git a/src/swap_lib_calls.h b/src/swap_lib_calls.h
index 9bdb11522..287034707 100644
--- a/src/swap_lib_calls.h
+++ b/src/swap_lib_calls.h
@@ -1,7 +1,15 @@
-#ifndef _SWAP_LIB_CALLS_H_
-#define _SWAP_LIB_CALLS_H_
+#pragma once
+
+/* This file is the shared API between Exchange and the apps started in Library mode for Exchange
+ *
+ * DO NOT MODIFY THIS FILE IN APPLICATIONS OTHER THAN EXCHANGE
+ * On modification in Exchange, forward the changes to all applications supporting Exchange
+ */
#include "stdbool.h"
+#include "chainConfig.h"
+#include "shared_context.h"
+#include "stdint.h"
#define RUN_APPLICATION 1
@@ -11,19 +19,27 @@
#define GET_PRINTABLE_AMOUNT 4
+/*
+ * Amounts are stored as bytes, with a max size of 16 (see protobuf
+ * specifications). Max 16B integer is 340282366920938463463374607431768211455
+ * in decimal, which is a 32-long char string.
+ * The printable amount also contains spaces, the ticker symbol (with variable
+ * size, up to 12 in Ethereum for instance) and a terminating null byte, so 50
+ * bytes total should be a fair maximum.
+ */
#define MAX_PRINTABLE_AMOUNT_SIZE 50
// structure that should be send to specific coin application to get address
typedef struct check_address_parameters_s {
// IN
- const unsigned char* const coin_configuration;
- const unsigned char coin_configuration_length;
+ uint8_t *coin_configuration;
+ uint8_t coin_configuration_length;
// serialized path, segwit, version prefix, hash used, dictionary etc.
- // fields and serialization format depends on spesific coin app
- const unsigned char* const address_parameters;
- const unsigned char address_parameters_length;
- const char* const address_to_check;
- const char* const extra_id_to_check;
+ // fields and serialization format depends on specific coin app
+ uint8_t *address_parameters;
+ uint8_t address_parameters_length;
+ char *address_to_check;
+ char *extra_id_to_check;
// OUT
int result;
} check_address_parameters_t;
@@ -31,25 +47,37 @@ typedef struct check_address_parameters_s {
// structure that should be send to specific coin application to get printable amount
typedef struct get_printable_amount_parameters_s {
// IN
- const unsigned char* const coin_configuration;
- const unsigned char coin_configuration_length;
- const unsigned char* const amount;
- const unsigned char amount_length;
- const bool is_fee;
+ uint8_t *coin_configuration;
+ uint8_t coin_configuration_length;
+ uint8_t *amount;
+ uint8_t amount_length;
+ bool is_fee;
// OUT
char printable_amount[MAX_PRINTABLE_AMOUNT_SIZE];
- // int result;
} get_printable_amount_parameters_t;
typedef struct create_transaction_parameters_s {
- const unsigned char* const coin_configuration;
- const unsigned char coin_configuration_length;
- const unsigned char* const amount;
- const unsigned char amount_length;
- const unsigned char* const fee_amount;
- const unsigned char fee_amount_length;
- const char* const destination_address;
- const char* const destination_address_extra_id;
+ // IN
+ uint8_t *coin_configuration;
+ uint8_t coin_configuration_length;
+ uint8_t *amount;
+ uint8_t amount_length;
+ uint8_t *fee_amount;
+ uint8_t fee_amount_length;
+ char *destination_address;
+ char *destination_address_extra_id;
+ // OUT
+ uint8_t result;
} create_transaction_parameters_t;
-#endif // _SWAP_LIB_CALLS_H_
+typedef struct libargs_s {
+ unsigned int id;
+ unsigned int command;
+ chain_config_t *chain_config;
+ union {
+ check_address_parameters_t *check_address;
+ create_transaction_parameters_t *create_transaction;
+ get_printable_amount_parameters_t *get_printable_amount;
+ caller_app_t *caller_app;
+ };
+} libargs_t;
diff --git a/src/tokens.c b/src/tokens.c
index e17e482c8..a513758bd 100644
--- a/src/tokens.c
+++ b/src/tokens.c
@@ -24,36 +24,36 @@ const tokenDefinition_t TOKENS_EXTRA[NUM_TOKENS_EXTRA] = {
// Ropsten DeversiFi tokens
{{0x4c, 0x5f, 0x66, 0x59, 0x61, 0x97, 0xa8, 0x6f, 0xb3, 0x0a,
0x24, 0x35, 0xe2, 0xef, 0x4d, 0xdc, 0xb3, 0x93, 0x42, 0xc9},
- "tUSDT ",
+ "tUSDT",
6},
{{0x1c, 0x0f, 0x17, 0x43, 0x67, 0x40, 0xbf, 0xb9, 0x2c, 0x10,
0x70, 0xee, 0x86, 0x32, 0x2d, 0xe8, 0x90, 0x83, 0x7c, 0x6a},
- "tUSDT ",
+ "tUSDT",
6},
{{0xcd, 0x07, 0x7a, 0xbe, 0xdd, 0x83, 0x1a, 0x34, 0x43, 0xff,
0xbe, 0x24, 0xfb, 0x76, 0x66, 0x1b, 0xbb, 0x17, 0xeb, 0x69},
- "tZRX ",
+ "tZRX",
18},
{{0x40, 0xd8, 0x97, 0x85, 0x00, 0xbf, 0x68, 0x32, 0x4a, 0x51,
0x53, 0x3c, 0xd6, 0xa2, 0x1e, 0x3e, 0x59, 0xbe, 0x32, 0x4a},
- "tBTC ",
+ "tBTC",
18},
// Goerli DeversiFi tokens
{{0xd9, 0x97, 0xa8, 0x63, 0x46, 0xe7, 0x65, 0x18, 0xe6, 0x92,
0x25, 0x56, 0xf3, 0x4d, 0x76, 0x61, 0x30, 0xc0, 0xbb, 0xfd},
- "tUSDT ",
+ "tUSDT",
6},
{{0xc1, 0xd5, 0x79, 0xeb, 0xff, 0x7c, 0x0f, 0x6c, 0xfd, 0x9a,
0xd5, 0xfb, 0x26, 0x7f, 0xec, 0x73, 0xbe, 0x70, 0xc8, 0xf7},
- "tBTC ",
+ "tBTC",
18},
{{0xa8, 0xf3, 0x14, 0x4f, 0xea, 0x2c, 0x37, 0x5a, 0xd0, 0x58,
0xec, 0x12, 0x09, 0x9a, 0x5a, 0x21, 0xa2, 0x6f, 0xe9, 0x96},
- "tDVF ",
+ "tDVF",
18},
{{0x4c, 0xda, 0xbe, 0xc1, 0x2a, 0x39, 0x7f, 0xb6, 0xef, 0xaf,
0x46, 0x13, 0xd5, 0xdf, 0xd7, 0x9b, 0x30, 0x9a, 0xe9, 0xfa},
- "tXDVF ",
+ "tXDVF",
18},
};
@@ -69,11 +69,11 @@ const tokenDefinition_t TOKENS_EXTRA[NUM_TOKENS_EXTRA] = {
const tokenDefinition_t const TOKENS_ETHEREUM[NUM_TOKENS_ETHEREUM] = {
{{0xdb, 0x25, 0xf2, 0x11, 0xab, 0x05, 0xb1, 0xc9, 0x7d, 0x59,
0x55, 0x16, 0xf4, 0x57, 0x94, 0x52, 0x8a, 0x80, 0x7a, 0xd8},
- "EURS ",
+ "EURS",
2},
{{0xa7, 0x44, 0x76, 0x44, 0x31, 0x19, 0xA9, 0x42, 0xdE, 0x49,
0x85, 0x90, 0xFe, 0x1f, 0x24, 0x54, 0xd7, 0xD4, 0xaC, 0x0d},
- "GNT ",
+ "GNT",
18},
};
@@ -89,19 +89,19 @@ const tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM] = {
const tokenDefinition_t const TOKENS_ETHEREUM_CLASSIC[NUM_TOKENS_ETHEREUM_CLASSIC] = {
{{0x6F, 0x6D, 0xEb, 0x5d, 0xb0, 0xC4, 0x99, 0x4A, 0x82, 0x83,
0xA0, 0x1D, 0x6C, 0xFe, 0xEB, 0x27, 0xFc, 0x3b, 0xBe, 0x9C},
- "Smart ",
+ "Smart",
0},
{{0x08, 0x5f, 0xb4, 0xf2, 0x40, 0x31, 0xea, 0xed, 0xbc, 0x2b,
0x61, 0x1a, 0xa5, 0x28, 0xf2, 0x23, 0x43, 0xeb, 0x52, 0xdb},
- "BEC ",
+ "BEC",
8},
{{0x5a, 0xce, 0x17, 0xf8, 0x7c, 0x73, 0x91, 0xe5, 0x79, 0x2a,
0x76, 0x83, 0x06, 0x9a, 0x80, 0x25, 0xb8, 0x3b, 0xbd, 0x85},
- "PLAY ",
+ "PLAY",
0},
{{0x6A, 0xDa, 0x6F, 0x48, 0xC8, 0x15, 0x68, 0x95, 0x02, 0xC4,
0x3e, 0xC1, 0xa5, 0x9F, 0x1b, 0x5D, 0xD3, 0xC0, 0x4E, 0x1F},
- "UNV ",
+ "UNV",
18},
};
@@ -118,27 +118,27 @@ const tokenDefinition_t const TOKENS_RSK[NUM_TOKENS_RSK] = {};
const tokenDefinition_t const TOKENS_UBIQ[NUM_TOKENS_UBIQ] = {
{{0xd2, 0x45, 0x20, 0x7c, 0xfb, 0xf6, 0xeb, 0x6f, 0x34, 0x97,
0x0d, 0xb2, 0xa8, 0x07, 0xab, 0x1d, 0x17, 0x8f, 0xde, 0x6c},
- "APX ",
+ "APX",
8},
{{0xff, 0x3b, 0xf0, 0x57, 0xad, 0xf3, 0xb0, 0xe0, 0x15, 0xb6,
0x46, 0x53, 0x31, 0xa6, 0x23, 0x6e, 0x55, 0x68, 0x82, 0x74},
- "BEER ",
+ "BEER",
0},
{{0x08, 0x53, 0x3d, 0x6a, 0x06, 0xce, 0x36, 0x52, 0x98, 0xb1,
0x2e, 0xf9, 0x2e, 0xb4, 0x07, 0xcb, 0xa8, 0xaa, 0x82, 0x73},
- "CEFS ",
+ "CEFS",
8},
{{0x94, 0xad, 0x7e, 0x41, 0xc1, 0xd4, 0x40, 0x22, 0xc4, 0xf4,
0x7c, 0xb1, 0xba, 0x01, 0x9f, 0xd1, 0xa0, 0x22, 0xc5, 0x36},
- "DOT ",
+ "DOT",
8},
{{0x4b, 0x48, 0x99, 0xa1, 0x0f, 0x3e, 0x50, 0x7d, 0xb2, 0x07,
0xb0, 0xee, 0x24, 0x26, 0x02, 0x9e, 0xfa, 0x16, 0x8a, 0x67},
- "QWARK ",
+ "QWARK",
8},
{{0x5e, 0x17, 0x15, 0xbb, 0x79, 0x80, 0x5b, 0xd6, 0x72, 0x72,
0x97, 0x60, 0xb3, 0xf7, 0xf3, 0x4d, 0x6f, 0x48, 0x50, 0x98},
- "RICKS ",
+ "RICKS",
8},
};
diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h
index 2035c27a9..041f7173e 100644
--- a/src/ui_callbacks.h
+++ b/src/ui_callbacks.h
@@ -4,6 +4,10 @@
#include "shared_context.h"
#include "ux.h"
+#ifdef HAVE_NBGL
+typedef int bagl_element_t;
+#endif
+
unsigned int io_seproxyhal_touch_settings(const bagl_element_t *e);
unsigned int io_seproxyhal_touch_exit(const bagl_element_t *e);
unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e);
diff --git a/src_bagl/ui_flow_signTx.c b/src_bagl/ui_flow_signTx.c
index 2b5592207..5d8e7b394 100644
--- a/src_bagl/ui_flow_signTx.c
+++ b/src_bagl/ui_flow_signTx.c
@@ -7,6 +7,7 @@
#include "eth_plugin_handler.h"
#include "ui_plugin.h"
#include "common_ui.h"
+#include "ethUtils.h"
#include "plugins.h"
#include "domain_name.h"
#include "ui_domain_name.h"
@@ -220,7 +221,7 @@ void ux_approve_tx(bool fromPlugin) {
// We're in a regular transaction, just show the amount and the address
ux_approval_tx_flow[step++] = &ux_approval_amount_step;
#ifdef HAVE_DOMAIN_NAME
- uint64_t chain_id = get_chain_id();
+ uint64_t chain_id = get_tx_chain_id();
if (has_domain_name(&chain_id, tmpContent.txContent.destination)) {
ux_approval_tx_flow[step++] = &ux_domain_name_step;
if (N_storage.verbose_domain_name) {
@@ -238,7 +239,7 @@ void ux_approve_tx(bool fromPlugin) {
ux_approval_tx_flow[step++] = &ux_approval_nonce_step;
}
- uint64_t chain_id = get_chain_id();
+ uint64_t chain_id = get_tx_chain_id();
if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) {
ux_approval_tx_flow[step++] = &ux_approval_network_step;
}
diff --git a/src_common/ethUtils.c b/src_common/ethUtils.c
index 4dd0e6a57..e66e0d2e5 100644
--- a/src_common/ethUtils.c
+++ b/src_common/ethUtils.c
@@ -27,9 +27,12 @@
#include
#include
+#include "shared_context.h"
+#include "utils.h"
#include "ethUtils.h"
#include "chainConfig.h"
#include "ethUstream.h"
+#include "network.h"
bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid) {
if (*buffer <= 0x7f) {
@@ -301,3 +304,32 @@ bool adjustDecimals(const char *src,
}
return true;
}
+
+// Returns the chain ID. Defaults to 0 if txType was not found (For TX).
+uint64_t get_tx_chain_id(void) {
+ uint64_t chain_id = 0;
+
+ switch (txContext.txType) {
+ case LEGACY:
+ chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength);
+ break;
+ case EIP2930:
+ case EIP1559:
+ chain_id = u64_from_BE(tmpContent.txContent.chainID.value,
+ tmpContent.txContent.chainID.length);
+ break;
+ default:
+ PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType);
+ break;
+ }
+ return chain_id;
+}
+
+const char *get_displayable_ticker(const uint64_t *chain_id) {
+ const char *ticker = get_network_ticker_from_chain_id(chain_id);
+
+ if (ticker == NULL) {
+ ticker = chainConfig->coinName;
+ }
+ return ticker;
+}
diff --git a/src_common/ethUtils.h b/src_common/ethUtils.h
index 9722e2c43..870253351 100644
--- a/src_common/ethUtils.h
+++ b/src_common/ethUtils.h
@@ -84,6 +84,10 @@ static __attribute__((no_instrument_function)) inline int ismaxint(uint8_t *buf,
return 1;
}
+uint64_t get_tx_chain_id(void);
+
+const char *get_displayable_ticker(const uint64_t *chain_id);
+
static const char HEXDIGITS[] = "0123456789abcdef";
#endif // _ETHUTILS_H_
diff --git a/src_common/network.c b/src_common/network.c
index f0dc4d1e5..8c0d238a6 100644
--- a/src_common/network.c
+++ b/src_common/network.c
@@ -1,11 +1,13 @@
-#include
-#include
-#include
#include
+#include "os_utils.h"
+#include "os_pic.h"
#include "network.h"
-#include "os.h"
-#include "shared_context.h"
-#include "utils.h"
+
+typedef struct network_info_s {
+ const char *name;
+ const char *ticker;
+ uint64_t chain_id;
+} network_info_t;
// Mappping of chain ids to networks.
static const network_info_t NETWORK_MAPPING[] = {
@@ -14,9 +16,11 @@ static const network_info_t NETWORK_MAPPING[] = {
{.chain_id = 4, .name = "Rinkeby", .ticker = "ETH"},
{.chain_id = 5, .name = "Goerli", .ticker = "ETH"},
{.chain_id = 10, .name = "Optimism", .ticker = "ETH"},
- {.chain_id = 42, .name = "Kovan", .ticker = "ETH"},
+ {.chain_id = 42, .name = "LUKSO", .ticker = "LYX"},
+ {.chain_id = 4201, .name = "LUKSO Testnet", .ticker = "LYXt"},
{.chain_id = 56, .name = "BSC", .ticker = "BNB"},
- {.chain_id = 100, .name = "xDai", .ticker = "xDAI"},
+ {.chain_id = 100, .name = "Gnosis", .ticker = "xDAI"},
+ {.chain_id = 10200, .name = "Chiado", .ticker = "xDAI"},
{.chain_id = 137, .name = "Polygon", .ticker = "MATIC"},
{.chain_id = 250, .name = "Fantom", .ticker = "FTM"},
{.chain_id = 42161, .name = "Arbitrum", .ticker = "ETH"},
@@ -62,51 +66,45 @@ static const network_info_t NETWORK_MAPPING[] = {
{.chain_id = 106, .name = "Velas EVM", .ticker = "VLX"},
{.chain_id = 288, .name = "Boba Network", .ticker = "ETH"},
{.chain_id = 39797, .name = "Energi", .ticker = "NRG"},
- {.chain_id = 248, .name = "Oasys", .ticker = "OAS"}};
-
-uint64_t get_chain_id(void) {
- uint64_t chain_id = 0;
-
- switch (txContext.txType) {
- case LEGACY:
- chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength);
- break;
- case EIP2930:
- case EIP1559:
- chain_id = u64_from_BE(tmpContent.txContent.chainID.value,
- tmpContent.txContent.chainID.length);
- break;
- default:
- PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType);
- break;
- }
- return chain_id;
-}
+ {.chain_id = 369, .name = "PulseChain", .ticker = "PLS"},
+ {.chain_id = 245022926, .name = "Neon EVM Devnet", .ticker = "NEON"},
+ {.chain_id = 245022934, .name = "Neon EVM Mainnet", .ticker = "NEON"},
+ {.chain_id = 4919, .name = "Venidium", .ticker = "XVM"},
+ {.chain_id = 40, .name = "Telos EVM Mainnet", .ticker = "TLOS"},
+ {.chain_id = 196, .name = "OKBChain Mainnet", .ticker = "OKB"},
+ {.chain_id = 248, .name = "Oasys", .ticker = "OAS"},
+ {.chain_id = 1101, .name = "Polygon zkEVM", .ticker = "ETH"},
+ {.chain_id = 8453, .name = "Base", .ticker = "ETH"},
+ {.chain_id = 58008, .name = "Sepolia", .ticker = "ETH"},
+};
-const network_info_t *get_network(void) {
- uint64_t chain_id = get_chain_id();
- for (size_t i = 0; i < sizeof(NETWORK_MAPPING) / sizeof(*NETWORK_MAPPING); i++) {
- if (NETWORK_MAPPING[i].chain_id == chain_id) {
- return (const network_info_t *) PIC(&NETWORK_MAPPING[i]);
+static const network_info_t *get_network_from_chain_id(const uint64_t *chain_id) {
+ for (size_t i = 0; i < ARRAYLEN(NETWORK_MAPPING); i++) {
+ if (NETWORK_MAPPING[i].chain_id == *chain_id) {
+ return (const network_info_t *) &NETWORK_MAPPING[i];
}
}
return NULL;
}
-const char *get_network_name(void) {
- const network_info_t *network = get_network();
- if (network == NULL) {
+const char *get_network_name_from_chain_id(const uint64_t *chain_id) {
+ const network_info_t *net = get_network_from_chain_id(chain_id);
+
+ if (net == NULL) {
return NULL;
- } else {
- return (const char *) PIC(network->name);
}
+ return PIC(net->name);
}
-const char *get_network_ticker(void) {
- const network_info_t *network = get_network();
- if (network == NULL) {
- return chainConfig->coinName;
- } else {
- return (char *) PIC(network->ticker);
+const char *get_network_ticker_from_chain_id(const uint64_t *chain_id) {
+ const network_info_t *net = get_network_from_chain_id(chain_id);
+
+ if (net == NULL) {
+ return NULL;
}
+ return PIC(net->ticker);
+}
+
+bool chain_is_ethereum_compatible(const uint64_t *chain_id) {
+ return get_network_from_chain_id(chain_id) != NULL;
}
diff --git a/src_common/network.h b/src_common/network.h
index b9ce7f31a..8361bcb9a 100644
--- a/src_common/network.h
+++ b/src_common/network.h
@@ -2,22 +2,11 @@
#define _NETWORK_H_
#include
-#include "tokens.h"
-#include "shared_context.h"
+#include
-typedef struct network_info_s {
- const char *name;
- const char *ticker;
- uint64_t chain_id;
-} network_info_t;
+const char *get_network_name_from_chain_id(const uint64_t *chain_id);
+const char *get_network_ticker_from_chain_id(const uint64_t *chain_id);
-// Returns the current chain id. Defaults to 0 if txType was not found.
-uint64_t get_chain_id(void);
-// Returns a pointer to the network struct, or NULL if there is none.
-const network_info_t *get_network(void);
-// Returns a pointer to the network name, or NULL if there is none.
-const char *get_network_name(void);
-// Returns a pointer to the network ticker, or chainConfig->coinName if there is none.
-const char *get_network_ticker(void);
+bool chain_is_ethereum_compatible(const uint64_t *chain_id);
#endif // _NETWORK_H_
diff --git a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
index 853d834fe..b1b38d5f1 100644
--- a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
+++ b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c
@@ -49,7 +49,7 @@ void handleGetEth2PublicKey(uint8_t p1,
unsigned int *tx) {
bip32_path_t bip32;
- if (!called_from_swap) {
+ if (!G_called_from_swap) {
reset_app_context();
}
if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c
index 07bab1df0..bc8bac6ce 100644
--- a/src_features/getPublicKey/cmd_getPublicKey.c
+++ b/src_features/getPublicKey/cmd_getPublicKey.c
@@ -16,7 +16,7 @@ void handleGetPublicKey(uint8_t p1,
bip32_path_t bip32;
cx_ecfp_private_key_t privateKey;
- if (!called_from_swap) {
+ if (!G_called_from_swap) {
reset_app_context();
}
diff --git a/src_features/provideDomainName/cmd_provide_domain_name.c b/src_features/provideDomainName/cmd_provide_domain_name.c
index 0d0849f26..e1d14a49c 100644
--- a/src_features/provideDomainName/cmd_provide_domain_name.c
+++ b/src_features/provideDomainName/cmd_provide_domain_name.c
@@ -10,6 +10,7 @@
#include "challenge.h"
#include "mem.h"
#include "hash_bytes.h"
+#include "network.h"
static const uint8_t DOMAIN_NAME_PUB_KEY[] = {
#ifdef HAVE_DOMAIN_NAME_TEST_KEY
@@ -124,8 +125,8 @@ bool has_domain_name(const uint64_t *chain_id, const uint8_t *addr) {
bool ret = false;
if (g_domain_name_info.valid) {
- // TODO: Remove once other domain name providers are supported
- if ((*chain_id == ETHEREUM_MAINNET_CHAINID) &&
+ // Check if chain ID is known to be Ethereum-compatible (same derivation path)
+ if ((chain_is_ethereum_compatible(chain_id)) &&
(memcmp(addr, g_domain_name_info.addr, ADDRESS_LENGTH) == 0)) {
ret = true;
}
@@ -478,7 +479,7 @@ static bool parse_der_value(const s_tlv_payload *payload, size_t *offset, uint32
if ((*offset + byte_length) > payload->size) {
PRINTF("TLV payload too small for DER encoded value\n");
} else {
- if (byte_length > sizeof(buf)) {
+ if (byte_length > sizeof(buf) || byte_length == 0) {
PRINTF("Unexpectedly long DER-encoded value (%u bytes)\n", byte_length);
} else {
memset(buf, 0, (sizeof(buf) - byte_length));
diff --git a/src_features/signMessageEIP712/commands_712.c b/src_features/signMessageEIP712/commands_712.c
index 7810b9335..a1cc45f9a 100644
--- a/src_features/signMessageEIP712/commands_712.c
+++ b/src_features/signMessageEIP712/commands_712.c
@@ -13,7 +13,8 @@
#include "schema_hash.h"
#include "filtering.h"
#include "common_712.h"
-#include "ethUtils.h" // allzeroes
+#include "ethUtils.h" // allzeroes
+#include "common_ui.h" // ui_idle
/**
* Send the response to the previous APDU command
@@ -38,6 +39,7 @@ void handle_eip712_return_code(bool success) {
if (!success) {
eip712_context_deinit();
+ ui_idle();
}
}
diff --git a/src_features/signMessageEIP712/context_712.c b/src_features/signMessageEIP712/context_712.c
index 82abd0935..57d5be6dd 100644
--- a/src_features/signMessageEIP712/context_712.c
+++ b/src_features/signMessageEIP712/context_712.c
@@ -72,7 +72,6 @@ void eip712_context_deinit(void) {
mem_reset();
eip712_context = NULL;
reset_app_context();
- ui_idle();
}
#endif
diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c
index ec95242c8..621d11dc5 100644
--- a/src_features/signMessageEIP712/path.c
+++ b/src_features/signMessageEIP712/path.c
@@ -143,14 +143,18 @@ static cx_sha3_t *get_last_hash_ctx(void) {
* Finalize the last hashing context
*
* @param[out] hash pointer to buffer where the hash will be stored
+ * @return whether there was anything hashed at this depth
*/
-static void finalize_hash_depth(uint8_t *hash) {
+static bool finalize_hash_depth(uint8_t *hash) {
const cx_sha3_t *hash_ctx;
+ size_t hashed_bytes;
hash_ctx = get_last_hash_ctx();
+ hashed_bytes = hash_ctx->blen;
// finalize hash
cx_hash((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE);
mem_dealloc(sizeof(*hash_ctx)); // remove hash context
+ return hashed_bytes > 0;
}
/**
@@ -192,6 +196,7 @@ static bool push_new_hash_depth(bool init) {
*/
static bool path_depth_list_pop(void) {
uint8_t hash[KECCAK256_HASH_BYTESIZE];
+ bool to_feed;
if (path_struct == NULL) {
return false;
@@ -201,9 +206,11 @@ static bool path_depth_list_pop(void) {
}
path_struct->depth_count -= 1;
- finalize_hash_depth(hash);
+ to_feed = finalize_hash_depth(hash);
if (path_struct->depth_count > 0) {
- feed_last_hash_depth(hash);
+ if (to_feed) {
+ feed_last_hash_depth(hash);
+ }
} else {
switch (path_struct->root_type) {
case ROOT_DOMAIN:
@@ -261,7 +268,7 @@ static bool array_depth_list_pop(void) {
return false;
}
- finalize_hash_depth(hash);
+ finalize_hash_depth(hash); // return value not checked on purpose
feed_last_hash_depth(hash);
path_struct->array_depth_count -= 1;
@@ -307,7 +314,10 @@ static bool path_update(void) {
}
feed_last_hash_depth(hash);
- ui_712_queue_struct_to_review();
+ // TODO: Find a better way to show inner structs in verbose mode when it might be
+ // an empty array of structs in which case we don't want to show it but the
+ // size is only known later
+ // ui_712_queue_struct_to_review();
path_depth_list_push();
}
return true;
@@ -421,6 +431,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
uint8_t total_count = 0;
uint8_t pidx;
bool is_custom;
+ uint8_t array_size;
+ uint8_t array_depth_count_bak;
if (path_struct == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
@@ -430,6 +442,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
return false;
}
+ array_size = *data;
+ array_depth_count_bak = path_struct->array_depth_count;
for (pidx = 0; pidx < path_struct->depth_count; ++pidx) {
if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
@@ -442,7 +456,7 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
}
total_count += depth_count;
if (total_count > path_struct->array_depth_count) {
- if (!check_and_add_array_depth(depth, total_count, pidx, *data)) {
+ if (!check_and_add_array_depth(depth, total_count, pidx, array_size)) {
return false;
}
break;
@@ -463,9 +477,18 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
cx_sha3_t *hash_ctx = get_last_hash_ctx();
cx_sha3_t *old_ctx = hash_ctx - 1;
- memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
+ if (array_size > 0) {
+ memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
+ } else {
+ cx_keccak_init(hash_ctx, 256);
+ }
cx_keccak_init(old_ctx, 256); // init hash
}
+ if (array_size == 0) {
+ do {
+ path_advance();
+ } while (path_struct->array_depth_count != array_depth_count_bak);
+ }
return true;
}
@@ -515,7 +538,7 @@ static bool path_advance_in_array(void) {
if ((path_struct->array_depth_count > 0) &&
(arr_depth->path_index == (path_struct->depth_count - 1))) {
- arr_depth->size -= 1;
+ if (arr_depth->size > 0) arr_depth->size -= 1;
if (arr_depth->size == 0) {
array_depth_list_pop();
end_reached = true;
diff --git a/src_features/signMessageEIP712_common/common_712.c b/src_features/signMessageEIP712_common/common_712.c
index abc1fd509..084a528bb 100644
--- a/src_features/signMessageEIP712_common/common_712.c
+++ b/src_features/signMessageEIP712_common/common_712.c
@@ -7,7 +7,7 @@
static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01};
-unsigned int ui_712_approve_cb() {
+unsigned int ui_712_approve_cb(void) {
uint8_t privateKeyData[INT256_LENGTH];
uint8_t hash[INT256_LENGTH];
uint8_t signature[100];
@@ -75,7 +75,7 @@ unsigned int ui_712_approve_cb() {
return 0; // do not redraw the widget
}
-unsigned int ui_712_reject_cb() {
+unsigned int ui_712_reject_cb(void) {
reset_app_context();
G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85;
diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c
index 199ccbbe0..a107439f5 100644
--- a/src_features/signTx/logic_signTx.c
+++ b/src_features/signTx/logic_signTx.c
@@ -136,6 +136,7 @@ customStatus_e customProcessor(txContext_t *context) {
}
dataContext.tokenContext.fieldIndex++;
dataContext.tokenContext.fieldOffset = 0;
+ memset(dataContext.tokenContext.data, 0, sizeof(dataContext.tokenContext.data));
return CUSTOM_HANDLED;
}
@@ -195,7 +196,8 @@ static void address_to_string(uint8_t *in,
}
static void raw_fee_to_string(uint256_t *rawFee, char *displayBuffer, uint32_t displayBufferSize) {
- const char *feeTicker = get_network_ticker();
+ uint64_t chain_id = get_tx_chain_id();
+ const char *feeTicker = get_displayable_ticker(&chain_id);
uint8_t tickerOffset = 0;
uint32_t i;
@@ -262,10 +264,10 @@ static void nonce_to_string(const txInt256_t *nonce, char *out, size_t out_size)
}
static void get_network_as_string(char *out, size_t out_size) {
- const char *name = get_network_name();
+ uint64_t chain_id = get_tx_chain_id();
+ const char *name = get_network_name_from_chain_id(&chain_id);
if (name == NULL) {
// No network name found so simply copy the chain ID as the network name.
- uint64_t chain_id = get_chain_id();
u64_to_string(chain_id, out, out_size);
} else {
// Network name found, simply copy it.
@@ -312,13 +314,14 @@ static int strcasecmp_workaround(const char *str1, const char *str2) {
void finalizeParsing(bool direct) {
char displayBuffer[50];
uint8_t decimals = WEI_TO_ETHER;
- const char *ticker = get_network_ticker();
+ uint64_t chain_id = get_tx_chain_id();
+ const char *ticker = get_displayable_ticker(&chain_id);
ethPluginFinalize_t pluginFinalize;
bool use_standard_UI = true;
// Verify the chain
if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) {
- uint64_t id = get_chain_id();
+ uint64_t id = get_tx_chain_id();
if (chainConfig->chainId != id) {
PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId);
@@ -423,8 +426,8 @@ void finalizeParsing(bool direct) {
}
// User has just validated a swap but ETH received apdus about a non standard plugin / contract
- if (called_from_swap && !use_standard_UI) {
- PRINTF("ERR_SILENT_MODE_CHECK_FAILED, called_from_swap\n");
+ if (G_called_from_swap && !use_standard_UI) {
+ PRINTF("ERR_SILENT_MODE_CHECK_FAILED, G_called_from_swap\n");
THROW(ERR_SILENT_MODE_CHECK_FAILED);
}
@@ -446,7 +449,7 @@ void finalizeParsing(bool direct) {
sizeof(displayBuffer),
&global_sha3,
chainConfig->chainId);
- if (called_from_swap) {
+ if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcasecmp_workaround(strings.common.fullAddress, displayBuffer) != 0) {
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, address check failed\n");
@@ -465,7 +468,7 @@ void finalizeParsing(bool direct) {
ticker,
displayBuffer,
sizeof(displayBuffer));
- if (called_from_swap) {
+ if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.fullAmount, displayBuffer) != 0) {
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, amount check failed\n");
@@ -483,7 +486,7 @@ void finalizeParsing(bool direct) {
&tmpContent.txContent.startgas,
displayBuffer,
sizeof(displayBuffer));
- if (called_from_swap) {
+ if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.maxFee, displayBuffer) != 0) {
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, fees check failed\n");
@@ -509,7 +512,7 @@ void finalizeParsing(bool direct) {
// If called from swap, the user as already validated a standard transaction
// We have already checked the fields of this transaction above
- no_consent_check = called_from_swap && use_standard_UI;
+ no_consent_check = G_called_from_swap && use_standard_UI;
#ifdef NO_CONSENT
no_consent_check = true;
diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c
index ef8171f25..e57bb2125 100644
--- a/src_features/signTx/ui_common_signTx.c
+++ b/src_features/signTx/ui_common_signTx.c
@@ -2,12 +2,14 @@
#include "shared_context.h"
#include "utils.h"
#include "common_ui.h"
+#include "handle_swap_sign_transaction.h"
unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_element_t *e) {
uint8_t privateKeyData[INT256_LENGTH];
uint8_t signature[100];
cx_ecfp_private_key_t privateKey;
uint32_t tx = 0;
+ int err;
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(CX_CURVE_256K1,
tmpCtx.transactionContext.bip32.path,
@@ -59,10 +61,19 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen
tx = 65;
G_io_apdu_buffer[tx++] = 0x90;
G_io_apdu_buffer[tx++] = 0x00;
+
// Send back the response, do not restart the event loop
- io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
- if (called_from_swap) {
- os_sched_exit(0);
+ err = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
+ if (G_called_from_swap) {
+ PRINTF("G_called_from_swap\n");
+
+ // If we are in swap mode and have validated a TX, we send it and immediately quit
+ if (err == 0) {
+ finalize_exchange_sign_transaction(true);
+ } else {
+ PRINTF("Unrecoverable\n");
+ os_sched_exit(-1);
+ }
}
reset_app_context();
// Display back the original UX
diff --git a/src_nbgl/ui_approve_tx.c b/src_nbgl/ui_approve_tx.c
new file mode 100644
index 000000000..a6253c35d
--- /dev/null
+++ b/src_nbgl/ui_approve_tx.c
@@ -0,0 +1,306 @@
+#include
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+#include "ethUtils.h"
+#include "ui_signing.h"
+#include "plugins.h"
+#include "domain_name.h"
+
+#define TEXT_TX "transaction"
+// 1 more than actually displayed on screen, because of calculations in StaticReview
+#define MAX_PLUGIN_ITEMS_PER_SCREEN 4
+#define TAG_MAX_LEN 43
+#define VALUE_MAX_LEN 79
+enum {
+ REJECT_TOKEN,
+ START_REVIEW_TOKEN,
+};
+
+static nbgl_layoutTagValue_t pair;
+// these buffers are used as circular
+static char title_buffer[MAX_PLUGIN_ITEMS_PER_SCREEN][TAG_MAX_LEN];
+static char msg_buffer[MAX_PLUGIN_ITEMS_PER_SCREEN][VALUE_MAX_LEN];
+static nbgl_layoutTagValueList_t useCaseTagValueList;
+static nbgl_pageInfoLongPress_t infoLongPress;
+
+struct tx_approval_context_t {
+ bool fromPlugin;
+ bool blindSigning;
+ bool displayNetwork;
+#ifdef HAVE_DOMAIN_NAME
+ bool domain_name_match;
+#endif
+};
+
+static struct tx_approval_context_t tx_approval_context;
+
+static void reviewContinueCommon(void);
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_tx_cancel(NULL);
+ memset(&tx_approval_context, 0, sizeof(tx_approval_context));
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_tx_ok(NULL);
+ memset(&tx_approval_context, 0, sizeof(tx_approval_context));
+}
+
+static void onConfirmAbandon(void) {
+ nbgl_useCaseStatus("Transaction rejected", false, reviewReject);
+}
+
+static void rejectTransactionQuestion(void) {
+ nbgl_useCaseConfirm(REJECT_QUESTION(TEXT_TX),
+ NULL,
+ REJECT_CONFIRM_BUTTON,
+ RESUME(TEXT_TX),
+ onConfirmAbandon);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ nbgl_useCaseStatus("TRANSACTION\nSIGNED", true, confirmTransation);
+ } else {
+ rejectTransactionQuestion();
+ }
+}
+
+// called by NBGL to get the tag/value pair corresponding to pairIndex
+static nbgl_layoutTagValue_t *getTagValuePair(uint8_t pairIndex) {
+ static int counter = 0;
+
+ if (tx_approval_context.fromPlugin) {
+ if (pairIndex < dataContext.tokenContext.pluginUiMaxItems) {
+ // for the next dataContext.tokenContext.pluginUiMaxItems items, get tag/value from
+ // plugin_ui_get_item_internal()
+ dataContext.tokenContext.pluginUiCurrentItem = pairIndex;
+ plugin_ui_get_item_internal((uint8_t *) title_buffer[counter],
+ TAG_MAX_LEN,
+ (uint8_t *) msg_buffer[counter],
+ VALUE_MAX_LEN);
+ pair.item = title_buffer[counter];
+ pair.value = msg_buffer[counter];
+ } else {
+ pairIndex -= dataContext.tokenContext.pluginUiMaxItems;
+ // for the last 1 (or 2), tags are fixed
+ if (tx_approval_context.displayNetwork && (pairIndex == 0)) {
+ pair.item = "Network";
+ pair.value = strings.common.network_name;
+ } else {
+ pair.item = "Max fees";
+ pair.value = strings.common.maxFee;
+ }
+ }
+ } else {
+ uint8_t target_index = 0;
+
+ if (pairIndex == target_index++) {
+ pair.item = "Amount";
+ pair.value = strings.common.fullAmount;
+ }
+#ifdef HAVE_DOMAIN_NAME
+ if (tx_approval_context.domain_name_match) {
+ if (pairIndex == target_index++) {
+ pair.item = "Domain";
+ pair.value = g_domain_name;
+ }
+ }
+ if (!tx_approval_context.domain_name_match || N_storage.verbose_domain_name) {
+#endif // HAVE_DOMAIN_NAME
+ if (pairIndex == target_index++) {
+ pair.item = "Address";
+ pair.value = strings.common.fullAddress;
+ }
+#ifdef HAVE_DOMAIN_NAME
+ }
+#endif // HAVE_DOMAIN_NAME
+ if (N_storage.displayNonce) {
+ if (pairIndex == target_index++) {
+ pair.item = "Nonce";
+ pair.value = strings.common.nonce;
+ }
+ }
+ if (pairIndex == target_index++) {
+ pair.item = "Max fees";
+ pair.value = strings.common.maxFee;
+ }
+ if (pairIndex == target_index++) {
+ pair.item = "Network";
+ pair.value = strings.common.network_name;
+ }
+ }
+ // counter is used as index to circular buffer
+ counter++;
+ if (counter == MAX_PLUGIN_ITEMS_PER_SCREEN) {
+ counter = 0;
+ }
+ return &pair;
+}
+
+static void pageCallback(int token, uint8_t index) {
+ (void) index;
+ nbgl_pageRelease(pageContext);
+ if (token == REJECT_TOKEN) {
+ reviewReject();
+ } else if (token == START_REVIEW_TOKEN) {
+ reviewContinueCommon();
+ }
+}
+
+static void reviewContinue(void) {
+ if (tx_approval_context.blindSigning) {
+ nbgl_pageInfoDescription_t info = {
+ .centeredInfo.icon = &C_round_warning_64px,
+ .centeredInfo.text1 = "Blind Signing",
+ .centeredInfo.text2 =
+ "This transaction cannot be\nsecurely interpreted by Ledger\nStax. It might put "
+ "your assets\nat risk.",
+ .centeredInfo.text3 = NULL,
+ .centeredInfo.style = LARGE_CASE_INFO,
+ .centeredInfo.offsetY = -32,
+ .footerText = REJECT(TEXT_TX),
+ .footerToken = REJECT_TOKEN,
+ .tapActionText = "Tap to continue",
+ .tapActionToken = START_REVIEW_TOKEN,
+ .topRightStyle = NO_BUTTON_STYLE,
+ .actionButtonText = NULL,
+ .tuneId = TUNE_TAP_CASUAL};
+
+ if (pageContext != NULL) {
+ nbgl_pageRelease(pageContext);
+ pageContext = NULL;
+ }
+ pageContext = nbgl_pageDrawInfo(&pageCallback, NULL, &info);
+ } else {
+ reviewContinueCommon();
+ }
+}
+
+static const nbgl_icon_details_t *get_tx_icon(void) {
+ const nbgl_icon_details_t *icon = NULL;
+
+ if (tx_approval_context.fromPlugin && (pluginType == EXTERNAL)) {
+ if (caller_app && caller_app->name) {
+ if ((strlen(strings.common.fullAddress) == strlen(caller_app->name)) &&
+ (strcmp(strings.common.fullAddress, caller_app->name) == 0)) {
+ icon = get_app_icon(true);
+ }
+ }
+ } else {
+ icon = get_app_icon(false);
+ }
+ return icon;
+}
+
+static void reviewContinueCommon(void) {
+ uint8_t nbPairs = 0;
+
+ if (tx_approval_context.fromPlugin) {
+ // plugin id + max items + fees
+ nbPairs += dataContext.tokenContext.pluginUiMaxItems + 1;
+ } else {
+ nbPairs += 3;
+ if (N_storage.displayNonce) {
+ nbPairs++;
+ }
+#ifdef HAVE_DOMAIN_NAME
+ uint64_t chain_id = get_tx_chain_id();
+ tx_approval_context.domain_name_match =
+ has_domain_name(&chain_id, tmpContent.txContent.destination);
+ if (tx_approval_context.domain_name_match && N_storage.verbose_domain_name) {
+ nbPairs += 1;
+ }
+#endif // HAVE_DOMAIN_NAME
+ }
+
+ if (tx_approval_context.displayNetwork) {
+ nbPairs++;
+ }
+
+ useCaseTagValueList.pairs = NULL;
+ useCaseTagValueList.callback = getTagValuePair;
+ useCaseTagValueList.startIndex = 0;
+ useCaseTagValueList.nbPairs = nbPairs; ///< number of pairs in pairs array
+ useCaseTagValueList.smallCaseForValue = false;
+ useCaseTagValueList.wrapping = false;
+ infoLongPress.icon = get_tx_icon();
+ infoLongPress.text = tx_approval_context.fromPlugin ? g_stax_shared_buffer : SIGN(TEXT_TX);
+ infoLongPress.longPressText = SIGN_BUTTON;
+ nbgl_useCaseStaticReview(&useCaseTagValueList, &infoLongPress, REJECT(TEXT_TX), reviewChoice);
+}
+
+// Replace "Review" by "Sign" and add questionmark
+static void prepare_sign_text(void) {
+ uint8_t sign_length = strlen("Sign");
+ uint8_t review_length = strlen("Review");
+
+ memmove(g_stax_shared_buffer, "Sign", sign_length);
+ memmove(g_stax_shared_buffer + sign_length,
+ g_stax_shared_buffer + review_length,
+ strlen(g_stax_shared_buffer) - review_length + 1);
+ strlcat(g_stax_shared_buffer, "?", sizeof(g_stax_shared_buffer));
+}
+
+// Force operation to be lowercase
+static void get_lowercase_operation(char *dst, size_t dst_len) {
+ const char *src = strings.common.fullAmount;
+ size_t idx;
+
+ for (idx = 0; (idx < dst_len - 1) && (src[idx] != '\0'); ++idx) {
+ dst[idx] = (char) tolower((int) src[idx]);
+ }
+ dst[idx] = '\0';
+}
+
+static void buildFirstPage(void) {
+ if (tx_approval_context.fromPlugin) {
+ char op_name[sizeof(strings.common.fullAmount)];
+ plugin_ui_get_id();
+
+ get_lowercase_operation(op_name, sizeof(op_name));
+ if (pluginType == EXTERNAL) {
+ snprintf(g_stax_shared_buffer,
+ sizeof(g_stax_shared_buffer),
+ "Review transaction\nto %s\non %s",
+ op_name,
+ strings.common.fullAddress);
+ } else {
+ snprintf(g_stax_shared_buffer,
+ sizeof(g_stax_shared_buffer),
+ "Review transaction\nto %s\n%s",
+ op_name,
+ strings.common.fullAddress);
+ }
+ nbgl_useCaseReviewStart(get_tx_icon(),
+ g_stax_shared_buffer,
+ NULL,
+ REJECT(TEXT_TX),
+ reviewContinue,
+ rejectTransactionQuestion);
+ prepare_sign_text();
+ } else {
+ nbgl_useCaseReviewStart(get_tx_icon(),
+ REVIEW(TEXT_TX),
+ NULL,
+ REJECT(TEXT_TX),
+ reviewContinue,
+ rejectTransactionQuestion);
+ }
+}
+
+void ux_approve_tx(bool fromPlugin) {
+ tx_approval_context.blindSigning =
+ !fromPlugin && tmpContent.txContent.dataPresent && !N_storage.contractDetails;
+ tx_approval_context.fromPlugin = fromPlugin;
+ tx_approval_context.displayNetwork = false;
+
+ uint64_t chain_id = get_tx_chain_id();
+ if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) {
+ tx_approval_context.displayNetwork = true;
+ }
+
+ buildFirstPage();
+}
diff --git a/src_nbgl/ui_confirm_parameter_selector.c b/src_nbgl/ui_confirm_parameter_selector.c
new file mode 100644
index 000000000..80418e18c
--- /dev/null
+++ b/src_nbgl/ui_confirm_parameter_selector.c
@@ -0,0 +1,83 @@
+#include "common_ui.h"
+#include "ui_signing.h"
+#include "ui_nbgl.h"
+#include "network.h"
+
+typedef enum { PARAMETER_CONFIRMATION, SELECTOR_CONFIRMATION } e_confirmation_type;
+
+static nbgl_layoutTagValue_t pair;
+static e_confirmation_type confirm_type;
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_data_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_data_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ confirmTransation();
+ } else {
+ reviewReject();
+ }
+}
+
+static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) {
+ if (page == 0) {
+ pair.item = (confirm_type == PARAMETER_CONFIRMATION) ? "Parameter" : "Selector";
+ pair.value = strings.tmp.tmp;
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 1;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) &pair;
+ } else if (page == 1) {
+ snprintf(g_stax_shared_buffer,
+ sizeof(g_stax_shared_buffer),
+ "Confirm %s",
+ (confirm_type == PARAMETER_CONFIRMATION) ? "parameter" : "selector");
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(true);
+ content->infoLongPress.text = g_stax_shared_buffer;
+ content->infoLongPress.longPressText = "Hold to confirm";
+ } else {
+ return false;
+ }
+ // valid page so return true
+ return true;
+}
+
+static void reviewContinue(void) {
+ snprintf(g_stax_shared_buffer,
+ sizeof(g_stax_shared_buffer),
+ "Reject %s",
+ (confirm_type == PARAMETER_CONFIRMATION) ? "parameter" : "selector");
+ nbgl_useCaseRegularReview(0,
+ 2,
+ g_stax_shared_buffer,
+ NULL,
+ displayTransactionPage,
+ reviewChoice);
+}
+
+static void buildScreen(void) {
+ snprintf(g_stax_shared_buffer,
+ sizeof(g_stax_shared_buffer),
+ "Verify %s",
+ (confirm_type == PARAMETER_CONFIRMATION) ? "parameter" : "selector");
+ nbgl_useCaseReviewStart(get_app_icon(true),
+ g_stax_shared_buffer,
+ NULL,
+ REJECT_BUTTON,
+ reviewContinue,
+ reviewReject);
+}
+
+void ui_confirm_parameter(void) {
+ confirm_type = PARAMETER_CONFIRMATION;
+ buildScreen();
+}
+
+void ui_confirm_selector(void) {
+ confirm_type = SELECTOR_CONFIRMATION;
+ buildScreen();
+}
diff --git a/src_nbgl/ui_display_privacy.c b/src_nbgl/ui_display_privacy.c
new file mode 100644
index 000000000..2b08175c9
--- /dev/null
+++ b/src_nbgl/ui_display_privacy.c
@@ -0,0 +1,69 @@
+#include "common_ui.h"
+#include "ui_signing.h"
+#include "ui_nbgl.h"
+#include "ui_callbacks.h"
+#include "nbgl_use_case.h"
+#include "network.h"
+
+static nbgl_layoutTagValue_t pairs[2];
+static char *review_string;
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_privacy_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_privacy_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ confirmTransation();
+ } else {
+ reviewReject();
+ }
+}
+
+static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) {
+ if (page == 0) {
+ pairs[0].item = "Address";
+ pairs[0].value = strings.common.fullAddress;
+ pairs[1].item = "Key";
+ pairs[1].value = strings.common.fullAmount;
+
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 2;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+ } else if (page == 1) {
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(true);
+ content->infoLongPress.text = review_string;
+ content->infoLongPress.longPressText = "Hold to approve";
+ } else {
+ return false;
+ }
+ // valid page so return true
+ return true;
+}
+
+static void reviewContinue(void) {
+ nbgl_useCaseRegularReview(0, 2, REJECT_BUTTON, NULL, displayTransactionPage, reviewChoice);
+}
+
+static void buildFirstPage(void) {
+ nbgl_useCaseReviewStart(get_app_icon(true),
+ review_string,
+ NULL,
+ REJECT_BUTTON,
+ reviewContinue,
+ reviewReject);
+}
+
+void ui_display_privacy_public_key(void) {
+ review_string = (char *) "Provide public\nprivacy key";
+ buildFirstPage();
+}
+
+void ui_display_privacy_shared_secret(void) {
+ review_string = (char *) "Provide public\nsecret key";
+ buildFirstPage();
+}
diff --git a/src_nbgl/ui_get_eth2_public_key.c b/src_nbgl/ui_get_eth2_public_key.c
new file mode 100644
index 000000000..9f388df27
--- /dev/null
+++ b/src_nbgl/ui_get_eth2_public_key.c
@@ -0,0 +1,30 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_address_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_address_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ // display a status page and go back to main
+ nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirmTransation);
+ } else {
+ nbgl_useCaseStatus("Address verification\ncancelled", false, reviewReject);
+ }
+}
+
+static void buildScreen(void) {
+ snprintf(strings.tmp.tmp, 100, "0x%.*H", 48, tmpCtx.publicKeyContext.publicKey.W);
+ nbgl_useCaseAddressConfirmation(strings.tmp.tmp, reviewChoice);
+}
+
+void ui_display_public_eth2(void) {
+ buildScreen();
+}
\ No newline at end of file
diff --git a/src_nbgl/ui_get_public_key.c b/src_nbgl/ui_get_public_key.c
new file mode 100644
index 000000000..5966737ea
--- /dev/null
+++ b/src_nbgl/ui_get_public_key.c
@@ -0,0 +1,28 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_address_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_address_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ // display a status page and go back to main
+ nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirmTransation);
+ } else {
+ nbgl_useCaseStatus("Address verification\ncancelled", false, reviewReject);
+ }
+}
+
+static void buildScreen(void) {
+ nbgl_useCaseAddressConfirmation(strings.common.fullAddress, reviewChoice);
+}
+void ui_display_public_key(void) {
+ buildScreen();
+}
\ No newline at end of file
diff --git a/src_nbgl/ui_get_stark_public_key.c b/src_nbgl/ui_get_stark_public_key.c
new file mode 100644
index 000000000..ce5778750
--- /dev/null
+++ b/src_nbgl/ui_get_stark_public_key.c
@@ -0,0 +1,29 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_address_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_stark_pubkey_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ // display a status page and go back to main
+ nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirmTransation);
+ } else {
+ nbgl_useCaseStatus("Address verification\ncancelled", false, reviewReject);
+ }
+}
+
+static void buildScreen(void) {
+ nbgl_useCaseAddressConfirmation(strings.tmp.tmp, reviewChoice);
+}
+
+void ui_display_stark_public(void) {
+ buildScreen();
+}
\ No newline at end of file
diff --git a/src_nbgl/ui_idle.c b/src_nbgl/ui_idle.c
new file mode 100644
index 000000000..faa47ca99
--- /dev/null
+++ b/src_nbgl/ui_idle.c
@@ -0,0 +1,63 @@
+#include "common_ui.h"
+#include "shared_context.h"
+#include "ui_nbgl.h"
+#include "nbgl_use_case.h"
+#include "glyphs.h"
+#include "network.h"
+
+char g_stax_shared_buffer[SHARED_BUFFER_SIZE] = {0};
+nbgl_page_t *pageContext;
+
+#define FORMAT_PLUGIN "This app enables clear\nsigning transactions for\nthe %s dApp."
+
+void releaseContext(void) {
+ if (pageContext != NULL) {
+ nbgl_pageRelease(pageContext);
+ pageContext = NULL;
+ }
+}
+
+void app_quit(void) {
+ // exit app here
+ os_sched_exit(-1);
+}
+
+const nbgl_icon_details_t *get_app_icon(bool caller_icon) {
+ const nbgl_icon_details_t *icon = NULL;
+
+ if (caller_icon && caller_app) {
+ if (caller_app->icon) {
+ icon = caller_app->icon;
+ }
+ } else {
+ icon = &ICONGLYPH;
+ }
+ if (icon == NULL) {
+ PRINTF("%s(%s) returned NULL!\n", __func__, (caller_icon ? "true" : "false"));
+ }
+ return icon;
+}
+
+void ui_idle(void) {
+ const char *app_name = NULL;
+ const char *tagline = NULL;
+
+ if (caller_app) {
+ app_name = caller_app->name;
+
+ if (caller_app->type == CALLER_TYPE_PLUGIN) {
+ snprintf(g_stax_shared_buffer, sizeof(g_stax_shared_buffer), FORMAT_PLUGIN, app_name);
+ tagline = g_stax_shared_buffer;
+ }
+ } else { // Ethereum app
+ uint64_t mainnet_chain_id = ETHEREUM_MAINNET_CHAINID;
+ app_name = get_network_name_from_chain_id(&mainnet_chain_id);
+ }
+
+ nbgl_useCaseHome((char *) app_name,
+ get_app_icon(true),
+ tagline,
+ true,
+ ui_menu_settings,
+ app_quit);
+}
diff --git a/src_nbgl/ui_message_signing.c b/src_nbgl/ui_message_signing.c
new file mode 100644
index 000000000..51e1a7ec2
--- /dev/null
+++ b/src_nbgl/ui_message_signing.c
@@ -0,0 +1,50 @@
+#include "ui_nbgl.h"
+#include "ui_signing.h"
+#include "ui_logic.h"
+#include "ui_message_signing.h"
+#include "glyphs.h"
+
+static void (*g_approved_func)(void) = NULL;
+static void (*g_rejected_func)(void) = NULL;
+
+static void ui_message_rejection_handler() {
+ nbgl_useCaseStatus("Message signing\ncancelled", false, g_rejected_func);
+}
+
+static void ui_message_confirm_rejection(void) {
+ nbgl_useCaseConfirm(REJECT_QUESTION(TEXT_MESSAGE),
+ NULL,
+ REJECT_CONFIRM_BUTTON,
+ RESUME(TEXT_MESSAGE),
+ ui_message_rejection_handler);
+}
+
+void ui_message_review_choice(bool confirm) {
+ if (confirm) {
+ nbgl_useCaseStatus("MESSAGE\nSIGNED", true, g_approved_func);
+ } else {
+ ui_message_confirm_rejection();
+ }
+}
+
+void ui_message_start(const char *title,
+ void (*start_func)(void),
+ void (*approved_func)(void),
+ void (*rejected_func)(void)) {
+ g_approved_func = approved_func;
+ g_rejected_func = rejected_func;
+ nbgl_useCaseReviewStart(&C_Message_64px,
+ title,
+ NULL,
+ REJECT_BUTTON,
+ start_func,
+ ui_message_confirm_rejection);
+}
+
+void ui_message_712_approved(void) {
+ ui_712_approve();
+}
+
+void ui_message_712_rejected(void) {
+ ui_712_reject();
+}
diff --git a/src_nbgl/ui_message_signing.h b/src_nbgl/ui_message_signing.h
new file mode 100644
index 000000000..008f57400
--- /dev/null
+++ b/src_nbgl/ui_message_signing.h
@@ -0,0 +1,20 @@
+#ifndef UI_MESSAGE_SIGNING_H_
+#define UI_MESSAGE_SIGNING_H_
+
+#include
+
+#define TEXT_MESSAGE "message"
+#define TEXT_TYPED_MESSAGE "typed " TEXT_MESSAGE
+#define TEXT_REVIEW_EIP712 REVIEW(TEXT_TYPED_MESSAGE)
+#define TEXT_SIGN_EIP712 SIGN(TEXT_TYPED_MESSAGE)
+
+void ui_message_review_choice(bool confirm);
+void ui_message_start(const char *title,
+ void (*start_func)(void),
+ void (*approved_func)(void),
+ void (*rejected_func)(void));
+
+void ui_message_712_approved(void);
+void ui_message_712_rejected(void);
+
+#endif // UI_MESSAGE_SIGNING_H_
diff --git a/src_nbgl/ui_nbgl.h b/src_nbgl/ui_nbgl.h
new file mode 100644
index 000000000..921d604d9
--- /dev/null
+++ b/src_nbgl/ui_nbgl.h
@@ -0,0 +1,21 @@
+#ifndef _UI_NBGL_H_
+#define _UI_NBGL_H_
+
+#include
+#include
+#include
+
+#define SHARED_BUFFER_SIZE SHARED_CTX_FIELD_1_SIZE
+extern char g_stax_shared_buffer[SHARED_BUFFER_SIZE];
+
+extern nbgl_page_t* pageContext;
+
+void releaseContext(void);
+
+const nbgl_icon_details_t* get_app_icon(bool caller_icon);
+
+void ui_idle(void);
+void ui_menu_settings(void);
+void ui_menu_about(void);
+
+#endif // _UI_NBGL_H_
diff --git a/src_nbgl/ui_settings.c b/src_nbgl/ui_settings.c
new file mode 100644
index 000000000..9d3656cc9
--- /dev/null
+++ b/src_nbgl/ui_settings.c
@@ -0,0 +1,132 @@
+#include "common_ui.h"
+#include "ui_nbgl.h"
+#include "nbgl_use_case.h"
+
+static const char* const infoTypes[] = {"Version", APPNAME " App"};
+static const char* const infoContents[] = {APPVERSION, "(c) " BUILD_YEAR " Ledger"};
+
+enum {
+ BLIND_SIGNING_TOKEN = FIRST_USER_TOKEN,
+ DEBUG_TOKEN,
+ NONCE_TOKEN,
+#ifdef HAVE_EIP712_FULL_SUPPORT
+ EIP712_VERBOSE_TOKEN,
+#endif // HAVE_EIP712_FULL_SUPPORT
+#ifdef HAVE_DOMAIN_NAME
+ DOMAIN_NAME_VERBOSE_TOKEN
+#endif // HAVE_DOMAIN_NAME
+};
+
+static nbgl_layoutSwitch_t switches[3];
+
+static bool navCallback(uint8_t page, nbgl_pageContent_t* content) {
+ uint8_t index = 0;
+
+ switch (page) {
+ case 0:
+ content->type = INFOS_LIST;
+ content->infosList.nbInfos = 2;
+ content->infosList.infoTypes = (const char**) infoTypes;
+ content->infosList.infoContents = (const char**) infoContents;
+ break;
+
+ case 1:
+ switches[index++] =
+ (nbgl_layoutSwitch_t){.initState = N_storage.dataAllowed ? ON_STATE : OFF_STATE,
+ .text = "Blind signing",
+ .subText = "Enable transaction blind\nsigning",
+ .token = BLIND_SIGNING_TOKEN,
+ .tuneId = TUNE_TAP_CASUAL};
+ switches[index++] =
+ (nbgl_layoutSwitch_t){.initState = N_storage.contractDetails ? ON_STATE : OFF_STATE,
+ .text = "Debug",
+ .subText = "Display contract data\ndetails",
+ .token = DEBUG_TOKEN,
+ .tuneId = TUNE_TAP_CASUAL};
+ switches[index++] =
+ (nbgl_layoutSwitch_t){.initState = N_storage.displayNonce ? ON_STATE : OFF_STATE,
+ .text = "Nonce",
+ .subText = "Display account nonce\nin transaction",
+ .token = NONCE_TOKEN,
+ .tuneId = TUNE_TAP_CASUAL};
+
+ content->type = SWITCHES_LIST;
+ content->switchesList.nbSwitches = index;
+ content->switchesList.switches = (nbgl_layoutSwitch_t*) switches;
+ break;
+
+ case 2:
+#ifdef HAVE_EIP712_FULL_SUPPORT
+ switches[index++] =
+ (nbgl_layoutSwitch_t){.initState = N_storage.verbose_eip712 ? ON_STATE : OFF_STATE,
+ .text = "Verbose EIP712",
+ .subText = "Ignore filtering and\ndisplay raw content",
+ .token = EIP712_VERBOSE_TOKEN,
+ .tuneId = TUNE_TAP_CASUAL};
+#endif // HAVE_EIP712_FULL_SUPPORT
+#ifdef HAVE_DOMAIN_NAME
+ switches[index++] = (nbgl_layoutSwitch_t){
+ .initState = N_storage.verbose_domain_name ? ON_STATE : OFF_STATE,
+ .text = "Verbose domains",
+ .subText = "Show resolved address",
+ .token = DOMAIN_NAME_VERBOSE_TOKEN,
+ .tuneId = TUNE_TAP_CASUAL};
+#endif // HAVE_DOMAIN_NAME
+
+ content->type = SWITCHES_LIST;
+ content->switchesList.nbSwitches = index;
+ content->switchesList.switches = (nbgl_layoutSwitch_t*) switches;
+ break;
+
+ default:
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+static void controlsCallback(int token, uint8_t index) {
+ (void) index;
+ uint8_t value;
+ switch (token) {
+ case BLIND_SIGNING_TOKEN:
+ value = (N_storage.dataAllowed ? 0 : 1);
+ nvm_write((void*) &N_storage.dataAllowed, (void*) &value, sizeof(uint8_t));
+ break;
+ case DEBUG_TOKEN:
+ value = (N_storage.contractDetails ? 0 : 1);
+ nvm_write((void*) &N_storage.contractDetails, (void*) &value, sizeof(uint8_t));
+ break;
+ case NONCE_TOKEN:
+ value = (N_storage.displayNonce ? 0 : 1);
+ nvm_write((void*) &N_storage.displayNonce, (void*) &value, sizeof(uint8_t));
+ break;
+#ifdef HAVE_EIP712_FULL_SUPPORT
+ case EIP712_VERBOSE_TOKEN:
+ value = (N_storage.verbose_eip712 ? 0 : 1);
+ nvm_write((void*) &N_storage.verbose_eip712, (void*) &value, sizeof(uint8_t));
+ break;
+#endif // HAVE_EIP712_FULL_SUPPORT
+#ifdef HAVE_DOMAIN_NAME
+ case DOMAIN_NAME_VERBOSE_TOKEN:
+ value = (N_storage.verbose_domain_name ? 0 : 1);
+ nvm_write((void*) &N_storage.verbose_domain_name, (void*) &value, sizeof(uint8_t));
+ break;
+#endif // HAVE_DOMAIN_NAME
+ }
+}
+
+void ui_menu_settings(void) {
+ uint8_t nb_screens = 2;
+#if defined(HAVE_EIP712_FULL_SUPPORT) || defined(HAVE_DOMAIN_NAME)
+ nb_screens += 1;
+#endif
+ nbgl_useCaseSettings(APPNAME " settings",
+ 0,
+ nb_screens,
+ false,
+ ui_idle,
+ navCallback,
+ controlsCallback);
+}
diff --git a/src_nbgl/ui_sign_712.c b/src_nbgl/ui_sign_712.c
new file mode 100644
index 000000000..4d9aae7a3
--- /dev/null
+++ b/src_nbgl/ui_sign_712.c
@@ -0,0 +1,87 @@
+#ifdef HAVE_EIP712_FULL_SUPPORT
+
+#include "common_ui.h"
+#include "ui_nbgl.h"
+#include "ui_logic.h"
+#include "common_712.h"
+#include "nbgl_use_case.h"
+#include "network.h"
+#include "ui_message_signing.h"
+#include "ui_signing.h"
+
+static nbgl_layoutTagValue_t pair;
+
+static bool display_sign_page(uint8_t page, nbgl_pageContent_t *content) {
+ (void) page;
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(true);
+ content->infoLongPress.text = TEXT_SIGN_EIP712;
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ return true;
+}
+
+static bool display_review_page(uint8_t page, nbgl_pageContent_t *content) {
+ bool ret;
+ uint16_t len;
+
+ switch (page) {
+ case 0:
+ // limit the value to one page
+ nbgl_getTextMaxLenInNbLines(BAGL_FONT_INTER_MEDIUM_32px,
+ strings.tmp.tmp,
+ SCREEN_WIDTH - (2 * BORDER_MARGIN),
+ NB_MAX_LINES_IN_REVIEW,
+ &len);
+ strings.tmp.tmp[len] = '\0';
+
+ pair.item = strings.tmp.tmp2;
+ pair.value = strings.tmp.tmp;
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 1;
+ content->tagValueList.pairs = &pair;
+ content->tagValueList.wrapping = false;
+ ret = true;
+ break;
+
+ case 1:
+ switch (ui_712_next_field()) {
+ case EIP712_NO_MORE_FIELD:
+ ui_712_switch_to_sign();
+ ret = true;
+ break;
+ case EIP712_FIELD_INCOMING:
+ case EIP712_FIELD_LATER:
+ default:
+ break;
+ }
+ __attribute__((fallthrough));
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+static void handle_display(nbgl_navCallback_t cb) {
+ nbgl_useCaseRegularReview(0, 0, REJECT_BUTTON, NULL, cb, ui_message_review_choice);
+}
+
+void ui_712_start(void) {
+ g_position = UI_SIGNING_POSITION_START;
+ ui_message_start(TEXT_REVIEW_EIP712,
+ &ui_712_switch_to_message,
+ &ui_message_712_approved,
+ &ui_message_712_rejected);
+}
+
+void ui_712_switch_to_message(void) {
+ g_position = UI_SIGNING_POSITION_REVIEW;
+ handle_display(display_review_page);
+}
+
+void ui_712_switch_to_sign(void) {
+ g_position = UI_SIGNING_POSITION_SIGN;
+ handle_display(display_sign_page);
+}
+
+#endif // HAVE_EIP712_FULL_SUPPORT
diff --git a/src_nbgl/ui_sign_712_v0.c b/src_nbgl/ui_sign_712_v0.c
new file mode 100644
index 000000000..ec38eeaf7
--- /dev/null
+++ b/src_nbgl/ui_sign_712_v0.c
@@ -0,0 +1,78 @@
+#include "common_ui.h"
+#include "ui_nbgl.h"
+#include "common_712.h"
+#include "network.h"
+#include "ethUtils.h"
+#include "ui_message_signing.h"
+#include "ui_signing.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);
+ return buffer + offset;
+}
+
+static bool display_review_page(uint8_t page, nbgl_pageContent_t *content) {
+ if (page == 0) {
+ pairs[0].item = "Domain hash";
+ pairs[0].value = format_hash(tmpCtx.messageSigningContext712.domainHash,
+ strings.tmp.tmp,
+ sizeof(strings.tmp.tmp),
+ 0);
+ pairs[1].item = "Message hash";
+ pairs[1].value = format_hash(tmpCtx.messageSigningContext712.messageHash,
+ strings.tmp.tmp,
+ sizeof(strings.tmp.tmp),
+ 70);
+
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 2;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+ } else if (page == 1) {
+ g_position = UI_SIGNING_POSITION_SIGN;
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(true);
+ content->infoLongPress.text = TEXT_SIGN_EIP712;
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ } else {
+ return false;
+ }
+ // valid page so return true
+ return true;
+}
+
+static void display_review(void) {
+ uint8_t page;
+
+ switch (g_position) {
+ case UI_SIGNING_POSITION_REVIEW:
+ page = 0;
+ break;
+ case UI_SIGNING_POSITION_SIGN:
+ page = 1;
+ break;
+ default:
+ return; // should not happen
+ }
+ nbgl_useCaseRegularReview(page,
+ 2,
+ REJECT_BUTTON,
+ NULL,
+ display_review_page,
+ ui_message_review_choice);
+}
+
+static void start_review(void) {
+ g_position = UI_SIGNING_POSITION_REVIEW;
+ display_review();
+}
+
+void ui_sign_712_v0(void) {
+ g_position = UI_SIGNING_POSITION_START;
+ ui_message_start(TEXT_REVIEW_EIP712,
+ &start_review,
+ &ui_message_712_approved,
+ &ui_message_712_rejected);
+}
diff --git a/src_nbgl/ui_sign_message.c b/src_nbgl/ui_sign_message.c
new file mode 100644
index 000000000..6d85f80e8
--- /dev/null
+++ b/src_nbgl/ui_sign_message.c
@@ -0,0 +1,154 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+#include "sign_message.h"
+#include "glyphs.h"
+#include "nbgl_use_case.h"
+#include "common_ui.h"
+#include "ui_message_signing.h"
+#include "ui_signing.h"
+
+#define TEXT_REVIEW_EIP191 REVIEW(TEXT_MESSAGE)
+#define TEXT_SIGN_EIP191 SIGN(TEXT_MESSAGE)
+
+typedef enum {
+ UI_191_ACTION_IDLE = 0,
+ UI_191_ACTION_ADVANCE_IN_MESSAGE,
+ UI_191_ACTION_GO_TO_SIGN
+} e_ui_191_action;
+
+static e_ui_191_action g_action;
+
+static bool skip_message;
+
+static nbgl_layoutTagValue_t pair;
+
+static uint32_t eip191MessageIdx = 0;
+static uint32_t stringsTmpTmpIdx = 0;
+
+static void reject_message(void) {
+ io_seproxyhal_touch_signMessage_cancel();
+}
+
+static void sign_message(void) {
+ io_seproxyhal_touch_signMessage_ok();
+}
+
+static bool display_message(nbgl_pageContent_t *content) {
+ uint16_t len = 0;
+ bool reached;
+
+ if (g_action == UI_191_ACTION_ADVANCE_IN_MESSAGE) {
+ strncpy(g_stax_shared_buffer + eip191MessageIdx,
+ strings.tmp.tmp + stringsTmpTmpIdx,
+ SHARED_BUFFER_SIZE - eip191MessageIdx);
+ reached = nbgl_getTextMaxLenInNbLines(BAGL_FONT_INTER_MEDIUM_32px,
+ (char *) g_stax_shared_buffer,
+ SCREEN_WIDTH - (2 * BORDER_MARGIN),
+ NB_MAX_LINES_IN_REVIEW,
+ &len);
+
+ stringsTmpTmpIdx = len - eip191MessageIdx;
+ eip191MessageIdx = len;
+ g_stax_shared_buffer[eip191MessageIdx] = '\0';
+
+ if (!reached && eip191MessageIdx < SHARED_BUFFER_SIZE) {
+ stringsTmpTmpIdx = 0;
+ question_switcher();
+
+ if (g_action != UI_191_ACTION_GO_TO_SIGN) {
+ return false;
+ }
+ } else if (reached || eip191MessageIdx == SHARED_BUFFER_SIZE) {
+ eip191MessageIdx = 0;
+ }
+ }
+
+ pair.value = g_stax_shared_buffer;
+ pair.item = "Message";
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 1;
+ content->tagValueList.pairs = &pair;
+ content->tagValueList.smallCaseForValue = false;
+ content->tagValueList.nbMaxLinesForValue = NB_MAX_LINES_IN_REVIEW;
+ content->tagValueList.wrapping = false;
+
+ if ((g_action != UI_191_ACTION_IDLE) && (stringsTmpTmpIdx >= strlen(strings.tmp.tmp))) {
+ // Fetch the next content to display into strings.tmp.tmp buffer.
+ stringsTmpTmpIdx = 0;
+ question_switcher();
+ }
+ return true;
+}
+
+static bool display_sign(nbgl_pageContent_t *content) {
+ bool ret = false;
+
+ if (g_position != UI_SIGNING_POSITION_SIGN) {
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = &C_Message_64px;
+ content->infoLongPress.text = TEXT_SIGN_EIP191;
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ g_position = UI_SIGNING_POSITION_SIGN;
+ ret = true;
+ }
+ return ret;
+}
+
+static bool nav_callback(uint8_t page, nbgl_pageContent_t *content) {
+ bool ret = true;
+
+ if (page == LAST_PAGE_FOR_REVIEW) { // was skipped
+ skip_message = true;
+ skip_rest_of_message();
+ }
+ if ((g_action != UI_191_ACTION_GO_TO_SIGN) && (g_position != UI_SIGNING_POSITION_SIGN)) {
+ if (skip_message) {
+ // do not refresh when this callback triggers after user validation
+ ret = false;
+ } else {
+ ret = display_message(content);
+ }
+ } else {
+ // the last page must contain a long press button
+ ret = display_sign(content);
+ }
+ return ret;
+}
+
+static void continue_review(void) {
+ nbgl_useCaseForwardOnlyReview(REJECT_BUTTON, NULL, nav_callback, ui_message_review_choice);
+}
+
+void ui_191_start(void) {
+ g_position = UI_SIGNING_POSITION_START;
+
+ skip_message = false;
+ eip191MessageIdx = 0;
+ stringsTmpTmpIdx = 0;
+
+ ui_message_start(TEXT_REVIEW_EIP191, &ui_191_switch_to_message, &sign_message, &reject_message);
+}
+
+void ui_191_switch_to_message(void) {
+ g_position = UI_SIGNING_POSITION_REVIEW;
+ g_action = UI_191_ACTION_ADVANCE_IN_MESSAGE;
+ // No question mechanism on Stax:
+ // Message is already displayed
+ continue_review();
+}
+
+void ui_191_switch_to_sign(void) {
+ g_action = UI_191_ACTION_GO_TO_SIGN;
+ // Next nav_callback callback must display
+ // the hold to approve screen
+ if (skip_message) {
+ continue_review(); // to force screen refresh
+ }
+}
+
+void ui_191_switch_to_question(void) {
+ // No question mechanism on Stax:
+ // Always display the next message chunk.
+ continue_displaying_message();
+}
diff --git a/src_nbgl/ui_signing.c b/src_nbgl/ui_signing.c
new file mode 100644
index 000000000..2becdf07d
--- /dev/null
+++ b/src_nbgl/ui_signing.c
@@ -0,0 +1,3 @@
+#include "ui_signing.h"
+
+e_ui_signing_position g_position;
diff --git a/src_nbgl/ui_signing.h b/src_nbgl/ui_signing.h
new file mode 100644
index 000000000..e7b8f71a2
--- /dev/null
+++ b/src_nbgl/ui_signing.h
@@ -0,0 +1,21 @@
+#ifndef UI_SIGNING_H_
+#define UI_SIGNING_H_
+
+#define SIGN_BUTTON "Hold to sign"
+#define REJECT_BUTTON "Reject"
+#define SIGN(msg) "Sign " msg "?"
+#define REVIEW(msg) "Review " msg
+#define REJECT(msg) "Reject " msg
+#define REJECT_QUESTION(msg) REJECT(msg) "?"
+#define REJECT_CONFIRM_BUTTON "Yes, reject"
+#define RESUME(msg) "Go back to " msg
+
+typedef enum {
+ UI_SIGNING_POSITION_START = 0,
+ UI_SIGNING_POSITION_REVIEW,
+ UI_SIGNING_POSITION_SIGN
+} e_ui_signing_position;
+
+extern e_ui_signing_position g_position;
+
+#endif // UI_SIGNING_H_
diff --git a/src_nbgl/ui_stark_limit_order.c b/src_nbgl/ui_stark_limit_order.c
new file mode 100644
index 000000000..89cfdbf83
--- /dev/null
+++ b/src_nbgl/ui_stark_limit_order.c
@@ -0,0 +1,68 @@
+#include "common_ui.h"
+#include "ui_signing.h"
+#include "ui_nbgl.h"
+#include "ui_callbacks.h"
+#include "nbgl_use_case.h"
+#include "network.h"
+
+#ifdef HAVE_STARKWARE
+
+static nbgl_layoutTagValue_t pairs[3];
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_tx_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_stark_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ confirmTransation();
+ } else {
+ reviewReject();
+ }
+}
+
+static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) {
+ if (page == 0) {
+ pairs[0].item = "Sell";
+ pairs[0].value = strings.common.fullAmount;
+ pairs[1].item = "Buy";
+ pairs[1].value = strings.common.maxFee;
+ pairs[2].item = "Token Account";
+ pairs[2].value = strings.common.fullAddress;
+
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 3;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+ } else if (page == 1) {
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false);
+ content->infoLongPress.text = "Review stark limit order";
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ } else {
+ return false;
+ }
+ // valid page so return true
+ return true;
+}
+
+static void reviewContinue(void) {
+ nbgl_useCaseRegularReview(0, 2, REJECT_BUTTON, NULL, displayTransactionPage, reviewChoice);
+}
+
+static void buildFirstPage(void) {
+ nbgl_useCaseReviewStart(get_app_icon(false),
+ "Review stark limit order",
+ NULL,
+ REJECT_BUTTON,
+ reviewContinue,
+ reviewReject);
+}
+
+void ui_stark_limit_order(void) {
+ buildFirstPage();
+}
+
+#endif
diff --git a/src_nbgl/ui_stark_transfer.c b/src_nbgl/ui_stark_transfer.c
new file mode 100644
index 000000000..d7decfbca
--- /dev/null
+++ b/src_nbgl/ui_stark_transfer.c
@@ -0,0 +1,133 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+#include "ui_signing.h"
+#include "starkDisplayUtils.h"
+#include "ethUtils.h"
+#include "network.h"
+
+#ifdef HAVE_STARKWARE
+
+static nbgl_layoutTagValue_t pairs[3];
+static char condAddressBuffer[43];
+struct stark_transfer_context {
+ bool selfTransfer;
+ bool conditional;
+};
+
+static struct stark_transfer_context context;
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_tx_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_stark_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ confirmTransation();
+ } else {
+ reviewReject();
+ }
+}
+
+static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) {
+ uint8_t count = 0;
+ if (page == 0) {
+ pairs[count].item = "Amount";
+ pairs[count].value = tmpContent.tmp;
+ count++;
+
+ if (context.selfTransfer == false && context.conditional == false) {
+ pairs[count].item = "Master Account";
+ pairs[count].value = strings.tmp.tmp;
+ count++;
+ }
+ if (context.conditional) {
+ stark_sign_display_master_account();
+ pairs[count].item = "Master Account";
+ pairs[count].value = strings.tmp.tmp;
+ count++;
+ }
+
+ pairs[count].item = "Token Account";
+ pairs[count].value = strings.tmp.tmp2;
+ count++;
+
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = count;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+
+ return true;
+ }
+ if (page == 1) {
+ if (context.conditional) {
+ getEthDisplayableAddress(dataContext.starkContext.conditionAddress,
+ condAddressBuffer,
+ sizeof(condAddressBuffer),
+ &global_sha3,
+ chainConfig->chainId);
+ pairs[0].item = "Cond. Address";
+ pairs[0].value = condAddressBuffer;
+
+ stark_sign_display_condition_fact();
+ pairs[1].item = "Cond. Address";
+ pairs[1].value = strings.tmp.tmp;
+
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 2;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+
+ return true;
+ } else {
+ page++;
+ }
+ }
+ if (page == 2) {
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false);
+ content->infoLongPress.text = "Review transaction";
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ return true;
+ }
+
+ return false;
+}
+
+static void reviewContinue(void) {
+ nbgl_useCaseRegularReview(0,
+ context.conditional ? 3 : 2,
+ REJECT_BUTTON,
+ NULL,
+ displayTransactionPage,
+ reviewChoice);
+}
+
+void ui_stark_transfer(bool selfTransfer, bool conditional) {
+ context.selfTransfer = selfTransfer;
+ context.conditional = conditional;
+ char *subTitle;
+ if (conditional) {
+ if (selfTransfer) {
+ subTitle = (char *) "Conditional Self Transfer";
+ } else {
+ subTitle = (char *) "Conditional Transfer";
+ }
+ } else {
+ if (selfTransfer) {
+ subTitle = (char *) "Self Transfer";
+ } else {
+ subTitle = (char *) "Transfer";
+ }
+ }
+ nbgl_useCaseReviewStart(get_app_icon(false),
+ "Review stark\ntransaction",
+ subTitle,
+ REJECT_BUTTON,
+ reviewContinue,
+ reviewReject);
+}
+
+#endif // #ifdef HAVE_STARKWARE
diff --git a/src_nbgl/ui_stark_unsafe_sign.c b/src_nbgl/ui_stark_unsafe_sign.c
new file mode 100644
index 000000000..45a8556db
--- /dev/null
+++ b/src_nbgl/ui_stark_unsafe_sign.c
@@ -0,0 +1,70 @@
+#include "common_ui.h"
+#include "ui_signing.h"
+#include "ui_nbgl.h"
+#include "ui_callbacks.h"
+#include "nbgl_use_case.h"
+#include "network.h"
+
+#ifdef HAVE_STARKWARE
+
+static nbgl_layoutTagValue_t pairs[2];
+static char from_account[64];
+static char message_hash[64];
+
+static void reviewReject(void) {
+ io_seproxyhal_touch_tx_cancel(NULL);
+}
+
+static void confirmTransation(void) {
+ io_seproxyhal_touch_stark_unsafe_sign_ok(NULL);
+}
+
+static void reviewChoice(bool confirm) {
+ if (confirm) {
+ confirmTransation();
+ } else {
+ reviewReject();
+ }
+}
+
+static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) {
+ snprintf(from_account, sizeof(from_account), "0x%.*H", 32, dataContext.starkContext.w1);
+ snprintf(message_hash, sizeof(message_hash), "0x%.*H", 32, dataContext.starkContext.w2);
+
+ if (page == 0) {
+ pairs[0].item = "From Account";
+ pairs[0].value = from_account;
+ pairs[1].item = "Hash";
+ pairs[1].value = message_hash;
+ content->type = TAG_VALUE_LIST;
+ content->tagValueList.nbPairs = 2;
+ content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs;
+ } else if (page == 1) {
+ content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false);
+ content->infoLongPress.text = "Unsafe Stark Sign";
+ content->infoLongPress.longPressText = SIGN_BUTTON;
+ } else {
+ return false;
+ }
+ // valid page so return true
+ return true;
+}
+
+static void reviewContinue(void) {
+ nbgl_useCaseRegularReview(0, 2, REJECT_BUTTON, NULL, displayTransactionPage, reviewChoice);
+}
+
+static void buildFirstPage(void) {
+ nbgl_useCaseReviewStart(get_app_icon(false),
+ "Unsafe Stark Sign",
+ NULL,
+ REJECT_BUTTON,
+ reviewContinue,
+ reviewReject);
+}
+
+void ui_stark_unsafe_sign(void) {
+ buildFirstPage();
+}
+
+#endif // HAVE_STARKWARE
diff --git a/src_nbgl/ui_warning_contract_data.c b/src_nbgl/ui_warning_contract_data.c
new file mode 100644
index 000000000..2619dce4e
--- /dev/null
+++ b/src_nbgl/ui_warning_contract_data.c
@@ -0,0 +1,21 @@
+#include
+#include "shared_context.h"
+#include "ui_callbacks.h"
+#include "ui_nbgl.h"
+
+static void ui_warning_contract_data_choice(bool confirm) {
+ if (confirm) {
+ ui_idle();
+ } else {
+ ui_menu_settings();
+ }
+}
+
+void ui_warning_contract_data(void) {
+ nbgl_useCaseChoice(&C_warning64px,
+ "This message cannot\nbe clear-signed",
+ "Enable blind-signing in\nthe settings to sign\nthis transaction.",
+ "Exit",
+ "Go to settings",
+ ui_warning_contract_data_choice);
+}
diff --git a/src_plugins/erc20/erc20_plugin.c b/src_plugins/erc20/erc20_plugin.c
index 04062d82e..220e05f9d 100644
--- a/src_plugins/erc20/erc20_plugin.c
+++ b/src_plugins/erc20/erc20_plugin.c
@@ -182,7 +182,11 @@ void erc20_plugin_call(int message, void *parameters) {
case ETH_PLUGIN_QUERY_CONTRACT_ID: {
ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters;
+#ifdef HAVE_NBGL
+ strlcpy(msg->name, "ERC20 token", msg->nameLength);
+#else
strlcpy(msg->name, "Type", msg->nameLength);
+#endif
strlcpy(msg->version, "Approve", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} break;
diff --git a/src_plugins/eth2/eth2_plugin.c b/src_plugins/eth2/eth2_plugin.c
index 29ea29947..c93c82ec6 100644
--- a/src_plugins/eth2/eth2_plugin.c
+++ b/src_plugins/eth2/eth2_plugin.c
@@ -212,7 +212,7 @@ void eth2_plugin_call(int message, void *parameters) {
strlcpy(msg->title, "Validator", msg->titleLength);
strlcpy(msg->msg, context->deposit_address, msg->msgLength);
msg->result = ETH_PLUGIN_RESULT_OK;
- }
+ } break;
default:
break;
}
diff --git a/tests/ragger/app/client.py b/tests/ragger/app/client.py
index 9732c81a6..616670c0a 100644
--- a/tests/ragger/app/client.py
+++ b/tests/ragger/app/client.py
@@ -2,14 +2,9 @@
from typing import Optional
from ragger.backend import BackendInterface
from ragger.utils import RAPDU
-from ragger.navigator import NavInsID, NavIns, NanoNavigator
-from .command_builder import EthereumCmdBuilder
-from .setting import SettingType, SettingImpl
+from .command_builder import CommandBuilder
from .eip712 import EIP712FieldType
-from .response_parser import EthereumRespParser
from .tlv import format_tlv
-import signal
-import time
from pathlib import Path
import keychain
import rlp
@@ -41,58 +36,19 @@ class DOMAIN_NAME_TAG(IntEnum):
ADDRESS = 0x22
-class EthereumClient:
- _settings: dict[SettingType, SettingImpl] = {
- SettingType.BLIND_SIGNING: SettingImpl(
- [ "nanos", "nanox", "nanosp" ]
- ),
- SettingType.DEBUG_DATA: SettingImpl(
- [ "nanos", "nanox", "nanosp" ]
- ),
- SettingType.NONCE: SettingImpl(
- [ "nanos", "nanox", "nanosp" ]
- ),
- SettingType.VERBOSE_EIP712: SettingImpl(
- [ "nanox", "nanosp" ]
- ),
- SettingType.VERBOSE_ENS: SettingImpl(
- [ "nanox", "nanosp" ]
- )
- }
- _click_delay = 1/4
- _eip712_filtering = False
-
- def __init__(self, client: BackendInterface, golden_run: bool):
+class EthAppClient:
+ def __init__(self, client: BackendInterface):
self._client = client
- self._chain_id = 1
- self._cmd_builder = EthereumCmdBuilder()
- self._resp_parser = EthereumRespParser()
- self._nav = NanoNavigator(client, client.firmware, golden_run)
- signal.signal(signal.SIGALRM, self._click_signal_timeout)
- for setting in self._settings.values():
- setting.value = False
+ self._cmd_builder = CommandBuilder()
def _send(self, payload: bytearray):
return self._client.exchange_async_raw(payload)
- def _recv(self) -> RAPDU:
+ def response(self) -> RAPDU:
return self._client._last_async_response
- def _click_signal_timeout(self, _signum: int, _frame):
- self._client.right_click()
-
- def _enable_click_until_response(self):
- signal.setitimer(signal.ITIMER_REAL,
- self._click_delay,
- self._click_delay)
-
- def _disable_click_until_response(self):
- signal.setitimer(signal.ITIMER_REAL, 0, 0)
-
def eip712_send_struct_def_struct_name(self, name: str):
- with self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name)):
- pass
- return self._recv().status == 0x9000
+ return self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name))
def eip712_send_struct_def_struct_field(self,
field_type: EIP712FieldType,
@@ -100,98 +56,45 @@ def eip712_send_struct_def_struct_field(self,
type_size: int,
array_levels: [],
key_name: str):
- with self._send(self._cmd_builder.eip712_send_struct_def_struct_field(
- field_type,
- type_name,
- type_size,
- array_levels,
- key_name)):
- pass
- return self._recv()
+ return self._send(self._cmd_builder.eip712_send_struct_def_struct_field(
+ field_type,
+ type_name,
+ type_size,
+ array_levels,
+ key_name))
def eip712_send_struct_impl_root_struct(self, name: str):
- with self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name)):
- self._enable_click_until_response()
- self._disable_click_until_response()
- return self._recv()
+ return self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name))
def eip712_send_struct_impl_array(self, size: int):
- with self._send(self._cmd_builder.eip712_send_struct_impl_array(size)):
- pass
- return self._recv()
+ return self._send(self._cmd_builder.eip712_send_struct_impl_array(size))
def eip712_send_struct_impl_struct_field(self, raw_value: bytes):
- for apdu in self._cmd_builder.eip712_send_struct_impl_struct_field(raw_value):
- with self._send(apdu):
- self._enable_click_until_response()
- self._disable_click_until_response()
- assert self._recv().status == 0x9000
-
- def eip712_sign_new(self, bip32_path: str):
- with self._send(self._cmd_builder.eip712_sign_new(bip32_path)):
- time.sleep(0.5) # tight on timing, needed by the CI otherwise might fail sometimes
- if not self._settings[SettingType.VERBOSE_EIP712].value and \
- not self._eip712_filtering: # need to skip the message hash
- self._client.right_click()
- self._client.right_click()
- self._client.both_click() # approve signature
- resp = self._recv()
- assert resp.status == 0x9000
- return self._resp_parser.sign(resp.data)
+ chunks = self._cmd_builder.eip712_send_struct_impl_struct_field(raw_value)
+ for chunk in chunks[:-1]:
+ with self._send(chunk):
+ pass
+ return self._send(chunks[-1])
+
+ def eip712_sign_new(self, bip32_path: str, verbose: bool):
+ return self._send(self._cmd_builder.eip712_sign_new(bip32_path))
def eip712_sign_legacy(self,
bip32_path: str,
domain_hash: bytes,
message_hash: bytes):
- with self._send(self._cmd_builder.eip712_sign_legacy(bip32_path,
- domain_hash,
- message_hash)):
- self._client.right_click() # sign typed message screen
- for _ in range(2): # two hashes (domain + message)
- if self._client.firmware.device == "nanos":
- screens_per_hash = 4
- else:
- screens_per_hash = 2
- for _ in range(screens_per_hash):
- self._client.right_click()
- self._client.both_click() # approve signature
-
- resp = self._recv()
-
- assert resp.status == 0x9000
- return self._resp_parser.sign(resp.data)
-
- def settings_set(self, new_values: dict[SettingType, bool]):
- # Go to settings
- for _ in range(2):
- self._client.right_click()
- self._client.both_click()
-
- for enum in self._settings.keys():
- if self._client.firmware.device in self._settings[enum].devices:
- if enum in new_values.keys():
- if new_values[enum] != self._settings[enum].value:
- self._client.both_click()
- self._settings[enum].value = new_values[enum]
- self._client.right_click()
- self._client.both_click()
+ return self._send(self._cmd_builder.eip712_sign_legacy(bip32_path,
+ domain_hash,
+ message_hash))
def eip712_filtering_activate(self):
- with self._send(self._cmd_builder.eip712_filtering_activate()):
- pass
- self._eip712_filtering = True
- assert self._recv().status == 0x9000
+ return self._send(self._cmd_builder.eip712_filtering_activate())
def eip712_filtering_message_info(self, name: str, filters_count: int, sig: bytes):
- with self._send(self._cmd_builder.eip712_filtering_message_info(name, filters_count, sig)):
- self._enable_click_until_response()
- self._disable_click_until_response()
- assert self._recv().status == 0x9000
+ return self._send(self._cmd_builder.eip712_filtering_message_info(name, filters_count, sig))
def eip712_filtering_show_field(self, name: str, sig: bytes):
- with self._send(self._cmd_builder.eip712_filtering_show_field(name, sig)):
- pass
- assert self._recv().status == 0x9000
+ return self._send(self._cmd_builder.eip712_filtering_show_field(name, sig))
def send_fund(self,
bip32_path: str,
@@ -200,8 +103,7 @@ def send_fund(self,
gas_limit: int,
to: bytes,
amount: float,
- chain_id: int,
- screenshot_collection: str = None):
+ chain_id: int):
data = list()
data.append(nonce)
data.append(gas_price)
@@ -213,27 +115,14 @@ def send_fund(self,
data.append(bytes())
data.append(bytes())
- for chunk in self._cmd_builder.sign(bip32_path, rlp.encode(data)):
+ chunks = self._cmd_builder.sign(bip32_path, rlp.encode(data))
+ for chunk in chunks[:-1]:
with self._send(chunk):
- nav_ins = NavIns(NavInsID.RIGHT_CLICK)
- final_ins = [ NavIns(NavInsID.BOTH_CLICK) ]
- target_text = "and send"
- if screenshot_collection:
- self._nav.navigate_until_text_and_compare(nav_ins,
- final_ins,
- target_text,
- ROOT_SCREENSHOT_PATH,
- screenshot_collection)
- else:
- self._nav.navigate_until_text(nav_ins,
- final_ins,
- target_text)
-
- def get_challenge(self) -> int:
- with self._send(self._cmd_builder.get_challenge()):
- pass
- resp = self._recv()
- return self._resp_parser.challenge(resp.data)
+ pass
+ return self._send(chunks[-1])
+
+ def get_challenge(self):
+ return self._send(self._cmd_builder.get_challenge())
def provide_domain_name(self, challenge: int, name: str, addr: bytes):
payload = format_tlv(DOMAIN_NAME_TAG.STRUCTURE_TYPE, 3) # TrustedDomainName
@@ -247,6 +136,8 @@ def provide_domain_name(self, challenge: int, name: str, addr: bytes):
payload += format_tlv(DOMAIN_NAME_TAG.SIGNATURE,
keychain.sign_data(keychain.Key.DOMAIN_NAME, payload))
- for chunk in self._cmd_builder.provide_domain_name(payload):
+ chunks = self._cmd_builder.provide_domain_name(payload)
+ for chunk in chunks[:-1]:
with self._send(chunk):
pass
+ return self._send(chunks[-1])
diff --git a/tests/ragger/app/command_builder.py b/tests/ragger/app/command_builder.py
index aac10d014..ae3f730f8 100644
--- a/tests/ragger/app/command_builder.py
+++ b/tests/ragger/app/command_builder.py
@@ -29,7 +29,7 @@ class P2Type(IntEnum):
FILTERING_CONTRACT_NAME = 0x0f
FILTERING_FIELD_NAME = 0xff
-class EthereumCmdBuilder:
+class CommandBuilder:
_CLA: int = 0xE0
def _serialize(self,
@@ -103,6 +103,7 @@ def eip712_send_struct_impl_array(self, size: int) -> bytes:
data)
def eip712_send_struct_impl_struct_field(self, data: bytearray) -> Iterator[bytes]:
+ chunks = list()
# Add a 16-bit integer with the data's byte length (network byte order)
data_w_length = bytearray()
data_w_length.append((len(data) & 0xff00) >> 8)
@@ -110,11 +111,12 @@ def eip712_send_struct_impl_struct_field(self, data: bytearray) -> Iterator[byte
data_w_length += data
while len(data_w_length) > 0:
p1 = P1Type.PARTIAL_SEND if len(data_w_length) > 0xff else P1Type.COMPLETE_SEND
- yield self._serialize(InsType.EIP712_SEND_STRUCT_IMPL,
- p1,
- P2Type.STRUCT_FIELD,
- data_w_length[:0xff])
+ chunks.append(self._serialize(InsType.EIP712_SEND_STRUCT_IMPL,
+ p1,
+ P2Type.STRUCT_FIELD,
+ data_w_length[:0xff]))
data_w_length = data_w_length[0xff:]
+ return chunks
def eip712_sign_new(self, bip32_path: str) -> bytes:
data = pack_derivation_path(bip32_path)
@@ -167,29 +169,33 @@ def eip712_filtering_show_field(self, name: str, sig: bytes) -> bytes:
P2Type.FILTERING_FIELD_NAME,
self._eip712_filtering_send_name(name, sig))
- def sign(self, bip32_path: str, rlp_data: bytes) -> Iterator[bytes]:
+ def sign(self, bip32_path: str, rlp_data: bytes) -> list[bytes]:
+ apdus = list()
payload = pack_derivation_path(bip32_path)
payload += rlp_data
p1 = P1Type.SIGN_FIRST_CHUNK
while len(payload) > 0:
- yield self._serialize(InsType.SIGN,
- p1,
- 0x00,
- payload[:0xff])
+ apdus.append(self._serialize(InsType.SIGN,
+ p1,
+ 0x00,
+ payload[:0xff]))
payload = payload[0xff:]
p1 = P1Type.SIGN_SUBSQT_CHUNK
+ return apdus
def get_challenge(self) -> bytes:
return self._serialize(InsType.GET_CHALLENGE, 0x00, 0x00)
- def provide_domain_name(self, tlv_payload: bytes) -> bytes:
+ def provide_domain_name(self, tlv_payload: bytes) -> list[bytes]:
+ chunks = list()
payload = struct.pack(">H", len(tlv_payload))
payload += tlv_payload
p1 = 1
while len(payload) > 0:
- yield self._serialize(InsType.PROVIDE_DOMAIN_NAME,
- p1,
- 0x00,
- payload[:0xff])
+ chunks.append(self._serialize(InsType.PROVIDE_DOMAIN_NAME,
+ p1,
+ 0x00,
+ payload[:0xff]))
payload = payload[0xff:]
p1 = 0
+ return chunks
diff --git a/tests/ragger/app/response_parser.py b/tests/ragger/app/response_parser.py
index 242f4cff5..5e73df498 100644
--- a/tests/ragger/app/response_parser.py
+++ b/tests/ragger/app/response_parser.py
@@ -1,18 +1,14 @@
-class EthereumRespParser:
- def sign(self, data: bytes):
- assert len(data) == (1 + 32 + 32)
+def signature(data: bytes) -> tuple[bytes, bytes, bytes]:
+ assert len(data) == (1 + 32 + 32)
- v = data[0:1]
- data = data[1:]
+ v = data[0:1]
+ data = data[1:]
+ r = data[0:32]
+ data = data[32:]
+ s = data[0:32]
- r = data[0:32]
- data = data[32:]
+ return v, r, s
- s = data[0:32]
- data = data[32:]
-
- return v, r, s
-
- def challenge(self, data: bytes) -> int:
- assert len(data) == 4
- return int.from_bytes(data, "big")
+def challenge(data: bytes) -> int:
+ assert len(data) == 4
+ return int.from_bytes(data, "big")
diff --git a/tests/ragger/app/setting.py b/tests/ragger/app/setting.py
deleted file mode 100644
index 7e79da72d..000000000
--- a/tests/ragger/app/setting.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from enum import IntEnum, auto
-from typing import List
-
-class SettingType(IntEnum):
- BLIND_SIGNING = 0,
- DEBUG_DATA = auto()
- NONCE = auto()
- VERBOSE_EIP712 = auto()
- VERBOSE_ENS = auto()
-
-class SettingImpl:
- devices: List[str]
- value: bool
-
- def __init__(self, devs: List[str]):
- self.devices = devs
diff --git a/tests/ragger/app/settings.py b/tests/ragger/app/settings.py
new file mode 100644
index 000000000..ec6bf78b4
--- /dev/null
+++ b/tests/ragger/app/settings.py
@@ -0,0 +1,63 @@
+from enum import Enum, auto
+from typing import List
+from ragger.firmware import Firmware
+from ragger.navigator import Navigator, NavInsID, NavIns
+
+class SettingID(Enum):
+ BLIND_SIGNING = auto()
+ DEBUG_DATA = auto()
+ NONCE = auto()
+ VERBOSE_EIP712 = auto()
+ VERBOSE_ENS = auto()
+
+def get_device_settings(device: str) -> list[SettingID]:
+ if device == "nanos":
+ return [
+ SettingID.BLIND_SIGNING,
+ SettingID.DEBUG_DATA,
+ SettingID.NONCE
+ ]
+ if (device == "nanox") or (device == "nanosp") or (device == "stax"):
+ return [
+ SettingID.BLIND_SIGNING,
+ SettingID.DEBUG_DATA,
+ SettingID.NONCE,
+ SettingID.VERBOSE_EIP712,
+ SettingID.VERBOSE_ENS
+ ]
+ return []
+
+settings_per_page = 3
+
+def get_setting_position(device: str, setting: NavInsID) -> tuple[int, int]:
+ screen_height = 672 # px
+ header_height = 85 # px
+ footer_height = 124 # px
+ usable_height = screen_height - (header_height + footer_height)
+ setting_height = usable_height // settings_per_page
+ index_in_page = get_device_settings(device).index(setting) % settings_per_page
+ return 350, header_height + (setting_height * index_in_page) + (setting_height // 2)
+
+def settings_toggle(fw: Firmware, nav: Navigator, to_toggle: list[SettingID]):
+ moves = list()
+ settings = get_device_settings(fw.device)
+ # Assume the app is on the home page
+ if fw.device.startswith("nano"):
+ moves += [NavInsID.RIGHT_CLICK] * 2
+ moves += [NavInsID.BOTH_CLICK]
+ for setting in settings:
+ if setting in to_toggle:
+ moves += [NavInsID.BOTH_CLICK]
+ moves += [NavInsID.RIGHT_CLICK]
+ moves += [NavInsID.BOTH_CLICK] # Back
+ else:
+ moves += [NavInsID.USE_CASE_HOME_SETTINGS]
+ moves += [NavInsID.USE_CASE_SETTINGS_NEXT]
+ for setting in settings:
+ setting_idx = settings.index(setting)
+ if (setting_idx > 0) and (setting_idx % settings_per_page) == 0:
+ moves += [NavInsID.USE_CASE_SETTINGS_NEXT]
+ if setting in to_toggle:
+ moves += [NavIns(NavInsID.TOUCH, get_setting_position(fw.device, setting))]
+ moves += [NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT]
+ nav.navigate(moves, screen_change_before_first_instruction=False)
diff --git a/tests/ragger/conftest.py b/tests/ragger/conftest.py
index 68799b278..6dd6f4ba3 100644
--- a/tests/ragger/conftest.py
+++ b/tests/ragger/conftest.py
@@ -1,12 +1,4 @@
-import pytest
from ragger.conftest import configuration
-from ragger.backend import BackendInterface
-from app.client import EthereumClient
-
-# This final fixture will return the properly configured app client, to be used in tests
-@pytest.fixture
-def app_client(backend: BackendInterface, golden_run: bool) -> EthereumClient:
- return EthereumClient(backend, golden_run)
# Pull all features from the base ragger conftest using the overridden configuration
pytest_plugins = ("ragger.conftest.base_conftest", )
diff --git a/tests/ragger/eip712/InputData.py b/tests/ragger/eip712/InputData.py
index 02a96ebd0..6dd647131 100644
--- a/tests/ragger/eip712/InputData.py
+++ b/tests/ragger/eip712/InputData.py
@@ -4,15 +4,19 @@
import sys
import re
import hashlib
-from app.client import EthereumClient, EIP712FieldType
+from app.client import EthAppClient, EIP712FieldType
import keychain
+from typing import Callable
+import signal
# global variables
-app_client: EthereumClient = None
+app_client: EthAppClient = None
filtering_paths = None
current_path = list()
sig_ctx = {}
+autonext_handler: Callable = None
+
@@ -97,11 +101,12 @@ def send_struct_def_field(typename, keyname):
type_enum = EIP712FieldType.CUSTOM
typesize = None
- app_client.eip712_send_struct_def_struct_field(type_enum,
- typename,
- typesize,
- array_lvls,
- keyname)
+ with app_client.eip712_send_struct_def_struct_field(type_enum,
+ typename,
+ typesize,
+ array_lvls,
+ keyname):
+ pass
return (typename, type_enum, typesize, array_lvls)
@@ -191,7 +196,9 @@ def send_struct_impl_field(value, field):
if path in filtering_paths.keys():
send_filtering_show_field(filtering_paths[path])
- app_client.eip712_send_struct_impl_struct_field(data)
+ with app_client.eip712_send_struct_impl_struct_field(data):
+ enable_autonext()
+ disable_autonext()
@@ -201,7 +208,8 @@ def evaluate_field(structs, data, field, lvls_left, new_level = True):
if new_level:
current_path.append(field["name"])
if len(array_lvls) > 0 and lvls_left > 0:
- app_client.eip712_send_struct_impl_array(len(data))
+ with app_client.eip712_send_struct_impl_array(len(data)):
+ pass
idx = 0
for subdata in data:
current_path.append("[]")
@@ -252,7 +260,9 @@ def send_filtering_message_info(display_name: str, filters_count: int):
to_sign.append(ord(char))
sig = keychain.sign_data(keychain.Key.CAL, to_sign)
- app_client.eip712_filtering_message_info(display_name, filters_count, sig)
+ with app_client.eip712_filtering_message_info(display_name, filters_count, sig):
+ enable_autonext()
+ disable_autonext()
# ledgerjs doesn't actually sign anything, and instead uses already pre-computed signatures
def send_filtering_show_field(display_name):
@@ -270,7 +280,8 @@ def send_filtering_show_field(display_name):
for char in display_name:
to_sign.append(ord(char))
sig = keychain.sign_data(keychain.Key.CAL, to_sign)
- app_client.eip712_filtering_show_field(display_name, sig)
+ with app_client.eip712_filtering_show_field(display_name, sig):
+ pass
def read_filtering_file(domain, message, filtering_file_path):
data_json = None
@@ -309,9 +320,29 @@ def init_signature_context(types, domain):
schema_hash = hashlib.sha224(schema_str.encode())
sig_ctx["schema_hash"] = bytearray.fromhex(schema_hash.hexdigest())
-def process_file(aclient: EthereumClient, input_file_path: str, filtering_file_path = None) -> bool:
+
+def next_timeout(_signum: int, _frame):
+ autonext_handler()
+
+def enable_autonext():
+ seconds = 1/4
+ if app_client._client.firmware.device == 'stax': # Stax Speculos is slow
+ interval = seconds * 3
+ else:
+ interval = seconds
+ signal.setitimer(signal.ITIMER_REAL, seconds, interval)
+
+def disable_autonext():
+ signal.setitimer(signal.ITIMER_REAL, 0, 0)
+
+
+def process_file(aclient: EthAppClient,
+ input_file_path: str,
+ filtering_file_path = None,
+ autonext: Callable = None) -> bool:
global sig_ctx
global app_client
+ global autonext_handler
app_client = aclient
with open(input_file_path, "r") as data:
@@ -322,23 +353,31 @@ def process_file(aclient: EthereumClient, input_file_path: str, filtering_file_p
domain = data_json["domain"]
message = data_json["message"]
+ if autonext:
+ autonext_handler = autonext
+ signal.signal(signal.SIGALRM, next_timeout)
+
if filtering_file_path:
init_signature_context(types, domain)
filtr = read_filtering_file(domain, message, filtering_file_path)
# send types definition
for key in types.keys():
- app_client.eip712_send_struct_def_struct_name(key)
+ with app_client.eip712_send_struct_def_struct_name(key):
+ pass
for f in types[key]:
(f["type"], f["enum"], f["typesize"], f["array_lvls"]) = \
send_struct_def_field(f["type"], f["name"])
if filtering_file_path:
- app_client.eip712_filtering_activate()
+ with app_client.eip712_filtering_activate():
+ pass
prepare_filtering(filtr, message)
# send domain implementation
- app_client.eip712_send_struct_impl_root_struct(domain_typename)
+ with app_client.eip712_send_struct_impl_root_struct(domain_typename):
+ enable_autonext()
+ disable_autonext()
if not send_struct_impl(types, domain, domain_typename):
return False
@@ -349,7 +388,9 @@ def process_file(aclient: EthereumClient, input_file_path: str, filtering_file_p
send_filtering_message_info(domain["name"], len(filtering_paths))
# send message implementation
- app_client.eip712_send_struct_impl_root_struct(message_typename)
+ with app_client.eip712_send_struct_impl_root_struct(message_typename):
+ enable_autonext()
+ disable_autonext()
if not send_struct_impl(types, message, message_typename):
return False
diff --git a/tests/ragger/eip712/input_files/13-empty_arrays-data.json b/tests/ragger/eip712/input_files/13-empty_arrays-data.json
new file mode 100644
index 000000000..7a1f93943
--- /dev/null
+++ b/tests/ragger/eip712/input_files/13-empty_arrays-data.json
@@ -0,0 +1,37 @@
+{
+ "domain": {
+ "chainId": 5,
+ "name": "Empty Arrays",
+ "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
+ "version": "1"
+ },
+ "message": {
+ "list1": [],
+ "list2": [],
+ "list3": [
+ [
+ "1",
+ "2"
+ ],
+ [],
+ [
+ "3",
+ "4"
+ ]
+ ]
+ },
+ "primaryType": "Struct",
+ "types": {
+ "EIP712Domain": [
+ { "name": "name", "type": "string" },
+ { "name": "version", "type": "string" },
+ { "name": "chainId", "type": "uint256" },
+ { "name": "verifyingContract", "type": "address" }
+ ],
+ "Struct": [
+ { "name": "list1", "type": "EIP712Domain[]" },
+ { "name": "list2", "type": "uint8[]" },
+ { "name": "list3", "type": "string[][]" }
+ ]
+ }
+}
diff --git a/tests/ragger/eip712/input_files/13-empty_arrays.ini b/tests/ragger/eip712/input_files/13-empty_arrays.ini
new file mode 100644
index 000000000..4784a4884
--- /dev/null
+++ b/tests/ragger/eip712/input_files/13-empty_arrays.ini
@@ -0,0 +1,4 @@
+[signature]
+v = 1b
+r = 5d0635a868602e29366da6328f8fadf2d6a9b4e69ee7a65928e85ca56fb1b515
+s = 257364d6faaf5687edf90c3984f4240b0ce7b2dee55aa1f8f39c32d0d4d8c93d
diff --git a/tests/ragger/requirements.txt b/tests/ragger/requirements.txt
index e408eadea..34213d69f 100644
--- a/tests/ragger/requirements.txt
+++ b/tests/ragger/requirements.txt
@@ -1,4 +1,4 @@
-ragger[speculos]>=1.6.0,<1.7.0
+ragger[speculos]
pytest
ecdsa
simple-rlp
diff --git a/tests/ragger/snapshots/nanosp b/tests/ragger/snapshots/nanosp
deleted file mode 120000
index da13a6af4..000000000
--- a/tests/ragger/snapshots/nanosp
+++ /dev/null
@@ -1 +0,0 @@
-nanox/
\ No newline at end of file
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00000.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00000.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00001.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00001.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00002.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00002.png
new file mode 100644
index 000000000..6af0ec54b
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00002.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00003.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00003.png
new file mode 100644
index 000000000..93112b3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00003.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00005.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00005.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png
new file mode 100644
index 000000000..a58590b98
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00000.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00000.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00002.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00002.png
new file mode 100644
index 000000000..6a5a9d64a
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00002.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00003.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00003.png
new file mode 100644
index 000000000..85a797b91
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00003.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00005.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00005.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png
new file mode 100644
index 000000000..a58590b98
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00000.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00000.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00001.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00001.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00002.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00002.png
new file mode 100644
index 000000000..6af0ec54b
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00002.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00004.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00004.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00004.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png
new file mode 100644
index 000000000..a58590b98
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00000.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00000.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00001.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00001.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00002.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00002.png
new file mode 100644
index 000000000..6af0ec54b
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00002.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00003.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00003.png
new file mode 100644
index 000000000..6a5a9d64a
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00003.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00005.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00005.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png
new file mode 100644
index 000000000..a58590b98
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00000.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00000.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00001.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00001.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00002.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00002.png
new file mode 100644
index 000000000..639e4214e
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00002.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png
new file mode 100644
index 000000000..70c1b9a68
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00004.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00004.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00004.png differ
diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png
new file mode 100644
index 000000000..a58590b98
Binary files /dev/null and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00002.png b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00002.png
index 6a5a9d64a..6af0ec54b 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00002.png and b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00002.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00004.png b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00004.png
index 70c1b9a68..1bcb78761 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00004.png and b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00004.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00006.png b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00006.png
index a58590b98..657887225 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00006.png and b/tests/ragger/snapshots/nanox/domain_name_non_mainnet/00006.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00000.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00000.png
new file mode 100644
index 000000000..487ea10fc
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00000.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png
new file mode 100644
index 000000000..f9840e3ab
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00002.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00002.png
new file mode 100644
index 000000000..6a5a9d64a
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00002.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00003.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00003.png
new file mode 100644
index 000000000..85a797b91
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00003.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png
new file mode 100644
index 000000000..1bcb78761
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00005.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00005.png
new file mode 100644
index 000000000..570ce28d5
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00005.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00006.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00006.png
new file mode 100644
index 000000000..657887225
Binary files /dev/null and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00006.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_verbose_False/00003.png b/tests/ragger/snapshots/nanox/domain_name_verbose_False/00003.png
index 70c1b9a68..1bcb78761 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_verbose_False/00003.png and b/tests/ragger/snapshots/nanox/domain_name_verbose_False/00003.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_verbose_False/00005.png b/tests/ragger/snapshots/nanox/domain_name_verbose_False/00005.png
index a58590b98..657887225 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_verbose_False/00005.png and b/tests/ragger/snapshots/nanox/domain_name_verbose_False/00005.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_verbose_True/00004.png b/tests/ragger/snapshots/nanox/domain_name_verbose_True/00004.png
index 70c1b9a68..1bcb78761 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_verbose_True/00004.png and b/tests/ragger/snapshots/nanox/domain_name_verbose_True/00004.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_verbose_True/00006.png b/tests/ragger/snapshots/nanox/domain_name_verbose_True/00006.png
index a58590b98..657887225 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_verbose_True/00006.png and b/tests/ragger/snapshots/nanox/domain_name_verbose_True/00006.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00003.png b/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00003.png
index 70c1b9a68..1bcb78761 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00003.png and b/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00003.png differ
diff --git a/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00005.png b/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00005.png
index a58590b98..657887225 100644
Binary files a/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00005.png and b/tests/ragger/snapshots/nanox/domain_name_wrong_addr/00005.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png
new file mode 100644
index 000000000..795ca0c2a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png
new file mode 100644
index 000000000..661ea68ef
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png
new file mode 100644
index 000000000..7f634cc4a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00004.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00004.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00004.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png
new file mode 100644
index 000000000..795ca0c2a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png
new file mode 100644
index 000000000..252785952
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png
new file mode 100644
index 000000000..592a8aca7
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png
new file mode 100644
index 000000000..299779759
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png
new file mode 100644
index 000000000..795ca0c2a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png
new file mode 100644
index 000000000..5e0c0a941
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png
new file mode 100644
index 000000000..7f634cc4a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png
new file mode 100644
index 000000000..795ca0c2a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png
new file mode 100644
index 000000000..ad8f07755
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png
new file mode 100644
index 000000000..e64dacc0f
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png
new file mode 100644
index 000000000..299779759
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png
new file mode 100644
index 000000000..795ca0c2a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png
new file mode 100644
index 000000000..3e505d39d
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png
new file mode 100644
index 000000000..7f634cc4a
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png differ
diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png
new file mode 100644
index 000000000..7a05bf7b3
Binary files /dev/null and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png differ
diff --git a/tests/ragger/test_domain_name.py b/tests/ragger/test_domain_name.py
index 317f72da4..f137610db 100644
--- a/tests/ragger/test_domain_name.py
+++ b/tests/ragger/test_domain_name.py
@@ -1,7 +1,11 @@
import pytest
from ragger.error import ExceptionRAPDU
-from app.client import EthereumClient, StatusWord
-from app.setting import SettingType
+from ragger.firmware import Firmware
+from ragger.backend import BackendInterface
+from ragger.navigator import Navigator, NavInsID
+from app.client import EthAppClient, StatusWord, ROOT_SCREENSHOT_PATH
+from app.settings import SettingID, settings_toggle
+import app.response_parser as ResponseParser
import struct
# Values used across all tests
@@ -20,108 +24,211 @@
def verbose(request) -> bool:
return request.param
-def common(app_client: EthereumClient) -> int:
+def common(app_client: EthAppClient) -> int:
if app_client._client.firmware.device == "nanos":
pytest.skip("Not supported on LNS")
- return app_client.get_challenge()
+ with app_client.get_challenge():
+ pass
+ return ResponseParser.challenge(app_client.response().data)
-def test_send_fund(app_client: EthereumClient, verbose: bool):
+def test_send_fund(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator,
+ test_name: str,
+ verbose: bool):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
if verbose:
- app_client.settings_set({
- SettingType.VERBOSE_ENS: True
- })
-
- app_client.provide_domain_name(challenge, NAME, ADDR)
-
- app_client.send_fund(BIP32_PATH,
- NONCE,
- GAS_PRICE,
- GAS_LIMIT,
- ADDR,
- AMOUNT,
- CHAIN_ID,
- "domain_name_verbose_" + str(verbose))
-
-def test_send_fund_wrong_challenge(app_client: EthereumClient):
+ settings_toggle(firmware, navigator, [SettingID.VERBOSE_ENS])
+
+ with app_client.provide_domain_name(challenge, NAME, ADDR):
+ pass
+
+ with app_client.send_fund(BIP32_PATH,
+ NONCE,
+ GAS_PRICE,
+ GAS_LIMIT,
+ ADDR,
+ AMOUNT,
+ CHAIN_ID):
+ moves = list()
+ if firmware.device.startswith("nano"):
+ moves += [ NavInsID.RIGHT_CLICK ] * 4
+ if verbose:
+ moves += [ NavInsID.RIGHT_CLICK ]
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2
+ if verbose:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ]
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
+ "domain_name_verbose_" + str(verbose),
+ moves)
+
+
+def test_send_fund_wrong_challenge(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
caught = False
challenge = common(app_client)
try:
- app_client.provide_domain_name(~challenge & 0xffffffff, NAME, ADDR)
+ with app_client.provide_domain_name(~challenge & 0xffffffff, NAME, ADDR):
+ pass
except ExceptionRAPDU as e:
assert e.status == StatusWord.INVALID_DATA
else:
assert False # An exception should have been raised
-def test_send_fund_wrong_addr(app_client: EthereumClient):
+
+def test_send_fund_wrong_addr(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator,
+ test_name: str):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
- app_client.provide_domain_name(challenge, NAME, ADDR)
+ with app_client.provide_domain_name(challenge, NAME, ADDR):
+ pass
addr = bytearray(ADDR)
addr.reverse()
- app_client.send_fund(BIP32_PATH,
- NONCE,
- GAS_PRICE,
- GAS_LIMIT,
- addr,
- AMOUNT,
- CHAIN_ID,
- "domain_name_wrong_addr")
-
-def test_send_fund_non_mainnet(app_client: EthereumClient):
+ with app_client.send_fund(BIP32_PATH,
+ NONCE,
+ GAS_PRICE,
+ GAS_LIMIT,
+ addr,
+ AMOUNT,
+ CHAIN_ID):
+ moves = list()
+ if firmware.device.startswith("nano"):
+ moves += [ NavInsID.RIGHT_CLICK ] * 4
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
+ "domain_name_wrong_addr",
+ moves)
+
+
+def test_send_fund_non_mainnet(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator,
+ test_name: str):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
- app_client.provide_domain_name(challenge, NAME, ADDR)
-
- app_client.send_fund(BIP32_PATH,
- NONCE,
- GAS_PRICE,
- GAS_LIMIT,
- ADDR,
- AMOUNT,
- 5,
- "domain_name_non_mainnet")
+ with app_client.provide_domain_name(challenge, NAME, ADDR):
+ pass
+
+ with app_client.send_fund(BIP32_PATH,
+ NONCE,
+ GAS_PRICE,
+ GAS_LIMIT,
+ ADDR,
+ AMOUNT,
+ 5):
+ moves = list()
+ if firmware.device.startswith("nano"):
+ moves += [ NavInsID.RIGHT_CLICK ] * 5
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
+ "domain_name_non_mainnet",
+ moves)
+
+
+def test_send_fund_unknown_chain(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator,
+ test_name: str):
+ app_client = EthAppClient(backend)
+ challenge = common(app_client)
-def test_send_fund_domain_too_long(app_client: EthereumClient):
+ with app_client.provide_domain_name(challenge, NAME, ADDR):
+ pass
+
+ with app_client.send_fund(BIP32_PATH,
+ NONCE,
+ GAS_PRICE,
+ GAS_LIMIT,
+ ADDR,
+ AMOUNT,
+ 9):
+ moves = list()
+ if firmware.device.startswith("nano"):
+ moves += [ NavInsID.RIGHT_CLICK ] * 5
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 3
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
+ "domain_name_unknown_chain",
+ moves)
+
+
+def test_send_fund_domain_too_long(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
try:
- app_client.provide_domain_name(challenge, "ledger" + "0"*25 + ".eth", ADDR)
+ with app_client.provide_domain_name(challenge, "ledger" + "0"*25 + ".eth", ADDR):
+ pass
except ExceptionRAPDU as e:
assert e.status == StatusWord.INVALID_DATA
else:
assert False # An exception should have been raised
-def test_send_fund_domain_invalid_character(app_client: EthereumClient):
+
+def test_send_fund_domain_invalid_character(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
try:
- app_client.provide_domain_name(challenge, "l\xe8dger.eth", ADDR)
+ with app_client.provide_domain_name(challenge, "l\xe8dger.eth", ADDR):
+ pass
except ExceptionRAPDU as e:
assert e.status == StatusWord.INVALID_DATA
else:
assert False # An exception should have been raised
-def test_send_fund_uppercase(app_client: EthereumClient):
+
+def test_send_fund_uppercase(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
try:
- app_client.provide_domain_name(challenge, NAME.upper(), ADDR)
+ with app_client.provide_domain_name(challenge, NAME.upper(), ADDR):
+ pass
except ExceptionRAPDU as e:
assert e.status == StatusWord.INVALID_DATA
else:
assert False # An exception should have been raised
-def test_send_fund_domain_non_ens(app_client: EthereumClient):
+
+def test_send_fund_domain_non_ens(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
challenge = common(app_client)
try:
- app_client.provide_domain_name(challenge, "ledger.hte", ADDR)
+ with app_client.provide_domain_name(challenge, "ledger.hte", ADDR):
+ pass
except ExceptionRAPDU as e:
assert e.status == StatusWord.INVALID_DATA
else:
diff --git a/tests/ragger/test_eip712.py b/tests/ragger/test_eip712.py
index 29cb84394..6ff0bc7b3 100644
--- a/tests/ragger/test_eip712.py
+++ b/tests/ragger/test_eip712.py
@@ -2,10 +2,17 @@
import os
import fnmatch
from typing import List
-from app.client import EthereumClient, SettingType
+from ragger.firmware import Firmware
+from ragger.backend import BackendInterface
+from ragger.navigator import Navigator, NavInsID
+from app.client import EthAppClient
+from app.settings import SettingID, settings_toggle
from eip712 import InputData
from pathlib import Path
from configparser import ConfigParser
+import app.response_parser as ResponseParser
+from functools import partial
+import time
BIP32_PATH = "m/44'/60'/0'/0/0"
@@ -30,19 +37,52 @@ def filtering(request) -> bool:
return request.param
-def test_eip712_legacy(app_client: EthereumClient):
- v, r, s = app_client.eip712_sign_legacy(
- BIP32_PATH,
- bytes.fromhex('6137beb405d9ff777172aa879e33edb34a1460e701802746c5ef96e741710e59'),
- bytes.fromhex('eb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8')
- )
+def test_eip712_legacy(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator):
+ app_client = EthAppClient(backend)
+ with app_client.eip712_sign_legacy(
+ BIP32_PATH,
+ bytes.fromhex('6137beb405d9ff777172aa879e33edb34a1460e701802746c5ef96e741710e59'),
+ bytes.fromhex('eb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8')):
+ moves = list()
+ if firmware.device.startswith("nano"):
+ moves += [ NavInsID.RIGHT_CLICK ]
+ if firmware.device == "nanos":
+ screens_per_hash = 4
+ else:
+ screens_per_hash = 2
+ moves += [ NavInsID.RIGHT_CLICK ] * screens_per_hash * 2
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate(moves)
+
+ v, r, s = ResponseParser.signature(app_client.response().data)
assert v == bytes.fromhex("1c")
assert r == bytes.fromhex("ea66f747173762715751c889fea8722acac3fc35db2c226d37a2e58815398f64")
assert s == bytes.fromhex("52d8ba9153de9255da220ffd36762c0b027701a3b5110f0a765f94b16a9dfb55")
-def test_eip712_new(app_client: EthereumClient, input_file: Path, verbose: bool, filtering: bool):
- if app_client._client.firmware.device == "nanos":
+
+def autonext(fw: Firmware, nav: Navigator):
+ moves = list()
+ if fw.device.startswith("nano"):
+ moves = [ NavInsID.RIGHT_CLICK ]
+ else:
+ moves = [ NavInsID.USE_CASE_REVIEW_TAP ]
+ nav.navigate(moves, screen_change_before_first_instruction=False, screen_change_after_last_instruction=False)
+
+
+def test_eip712_new(firmware: Firmware,
+ backend: BackendInterface,
+ navigator: Navigator,
+ input_file: Path,
+ verbose: bool,
+ filtering: bool):
+ app_client = EthAppClient(backend)
+ if firmware.device == "nanos":
pytest.skip("Not supported on LNS")
else:
test_path = "%s/%s" % (input_file.parent, "-".join(input_file.stem.split("-")[:-1]))
@@ -63,12 +103,25 @@ def test_eip712_new(app_client: EthereumClient, input_file: Path, verbose: bool,
if not filtering or Path(filter_file).is_file():
if verbose:
- app_client.settings_set({
- SettingType.VERBOSE_EIP712: True
- })
-
- assert InputData.process_file(app_client, input_file, filter_file) == True
- v, r, s = app_client.eip712_sign_new(BIP32_PATH)
+ settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712])
+
+ assert InputData.process_file(app_client,
+ input_file,
+ filter_file,
+ partial(autonext, firmware, navigator)) == True
+ with app_client.eip712_sign_new(BIP32_PATH, verbose):
+ time.sleep(0.5) # tight on timing, needed by the CI otherwise might fail sometimes
+ moves = list()
+ if firmware.device.startswith("nano"):
+ if not verbose and not filtering: # need to skip the message hash
+ moves = [ NavInsID.RIGHT_CLICK ] * 2
+ moves += [ NavInsID.BOTH_CLICK ]
+ else:
+ if not verbose and not filtering: # need to skip the message hash
+ moves += [ NavInsID.USE_CASE_REVIEW_TAP ]
+ moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ]
+ navigator.navigate(moves)
+ v, r, s = ResponseParser.signature(app_client.response().data)
#print("[signature]")
#print("v = %s" % (v.hex()))
#print("r = %s" % (r.hex()))
diff --git a/tests/speculos/README.md b/tests/speculos/README.md
index c3bb346cb..68d146878 100644
--- a/tests/speculos/README.md
+++ b/tests/speculos/README.md
@@ -11,9 +11,8 @@ These tests are implemented in Python with the `SpeculosClient` interface which
Python dependencies are listed in [requirements.txt](requirements.txt)
```shell
-python3 -m pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt
+python3 -m pip install -r requirements.txt
```
-> The extra index allows to fetch the latest version of Speculos.
## Usage
@@ -47,4 +46,4 @@ pytest --model nanox --path ./elfs/nanox.elf
# Execute specific test:
pytest --model nanox --path ./elfs/nanox.elf test_pubkey_cmd.py
-```
\ No newline at end of file
+```
diff --git a/tests/speculos/test_configuration_cmd.py b/tests/speculos/test_configuration_cmd.py
index 1d848391b..8027b2cf8 100644
--- a/tests/speculos/test_configuration_cmd.py
+++ b/tests/speculos/test_configuration_cmd.py
@@ -1,10 +1,10 @@
def test_configuration(cmd):
if cmd.model == "nanos":
- assert cmd.get_configuration() == (14, 1, 10, 2)
+ assert cmd.get_configuration() == (14, 1, 10, 3)
if cmd.model == "nanox":
- assert cmd.get_configuration() == (14, 1, 10, 2)
+ assert cmd.get_configuration() == (14, 1, 10, 3)
if cmd.model == "nanosp":
- assert cmd.get_configuration() == (14, 1, 10, 2)
+ assert cmd.get_configuration() == (14, 1, 10, 3)
diff --git a/tools/build_sdk.py b/tools/build_sdk.py
index a808e4aed..552bb25cf 100755
--- a/tools/build_sdk.py
+++ b/tools/build_sdk.py
@@ -82,10 +82,13 @@ def extract_from_c_files(sources, nodes_to_extract):
def merge_headers(sources, nodes_to_extract):
includes = [
+ '#include ',
+ '#include ',
'#include "os.h"',
'#include "cx.h"',
- '#include ',
- '#include '
+ '#ifdef HAVE_NBGL',
+ '#include "nbgl_types.h"',
+ '#endif'
]
body = extract_from_headers(sources, nodes_to_extract)
@@ -156,11 +159,12 @@ def merge_c_files(sources, nodes_to_extract):
"src/shared_context.h",
"src/eth_plugin_internal.h",
"src/nft.h",
+ "src/swap_lib_calls.h"
]
nodes_to_extract = {
"#define": ["MAX_TICKER_LEN", "ADDRESS_LENGTH", "INT256_LENGTH", "WEI_TO_ETHER", "SELECTOR_SIZE", "PARAMETER_LENGTH", "RUN_APPLICATION", "COLLECTION_NAME_MAX_LEN"],
"typedef enum": [],
- "typedef struct": ["tokenDefinition_t", "txInt256_t", "txContent_t", "nftInfo_t"],
+ "typedef struct": ["tokenDefinition_t", "txInt256_t", "txContent_t", "nftInfo_t", "caller_app_t"],
"typedef union": ["extraInfo_t"],
"__attribute__((no_instrument_function)) inline": ["int allzeroes"],
"const": ["HEXDIGITS"],