diff --git a/CHANGELOG.md b/CHANGELOG.md index e7aaa17..5843b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 2.0.0 - 2024-05-01 + +- Support of Flex device + ## 1.7.6 - 2021-03-30 - Support of Monero client version `0.17.2.*` diff --git a/Makefile b/Makefile index 8f7068d..5d01240 100644 --- a/Makefile +++ b/Makefile @@ -27,8 +27,8 @@ include $(BOLOS_SDK)/Makefile.defines APPNAME = "Monero" # Application version -APPVERSION_M = 1 -APPVERSION_N = 9 +APPVERSION_M = 2 +APPVERSION_N = 0 APPVERSION_P = 0 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" @@ -43,6 +43,7 @@ ICON_NANOS = icons/app_monero_16px.gif ICON_NANOX = icons/app_monero_14px.gif ICON_NANOSP = icons/app_monero_14px.gif ICON_STAX = icons/app_monero_32px.gif +ICON_FLEX = icons/app_monero_40px.gif # Application allowed derivation curves. CURVE_APP_LOAD_PARAMS = secp256k1 diff --git a/README.md b/README.md index dc9d137..08fb891 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Monero Ledger App -Monero wallet application for Ledger Nano S and Nano X. +Monero wallet application for all Ledger devices. ## Install diff --git a/icons/app_monero_40px.gif b/icons/app_monero_40px.gif new file mode 100644 index 0000000..0cc57ad Binary files /dev/null and b/icons/app_monero_40px.gif differ diff --git a/ledger_app.toml b/ledger_app.toml index c264aa9..7329320 100644 --- a/ledger_app.toml +++ b/ledger_app.toml @@ -1,7 +1,7 @@ [app] build_directory = "./" sdk = "C" -devices = ["nanos", "nanox", "nanos+", "stax"] +devices = ["nanos", "nanox", "nanos+", "stax", "flex"] [tests] pytest_directory = "./tests/" diff --git a/src/monero_nvram.c b/src/monero_nvram.c index 495f881..fe326b9 100644 --- a/src/monero_nvram.c +++ b/src/monero_nvram.c @@ -22,7 +22,7 @@ #include "monero_api.h" #include "monero_vars.h" -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) +#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) || defined(TARGET_FLEX) const monero_nv_state_t N_state_pic; #else monero_nv_state_t N_state_pic; diff --git a/src/monero_ux_stax.c b/src/monero_ux_nbgl.c similarity index 95% rename from src/monero_ux_stax.c rename to src/monero_ux_nbgl.c index 7189fb7..c99d708 100644 --- a/src/monero_ux_stax.c +++ b/src/monero_ux_nbgl.c @@ -59,7 +59,7 @@ static void release_context(void) { /* -------------------------------- INFO UX --------------------------------- */ void ui_menu_show_tx_aborted(void) { - nbgl_useCaseStatus("Transaction\ncancelled", false, ui_menu_main_display); + nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_REJECTED, ui_menu_main_display); } void ui_menu_show_security_error(void) { @@ -103,7 +103,7 @@ unsigned int ui_menu_transaction_start(void) { } unsigned int ui_menu_transaction_signed(void) { - nbgl_useCaseStatus("TRANSACTION\nSIGNED", true, ui_menu_main_display); + nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_SIGNED, ui_menu_main_display); return 0; } @@ -315,7 +315,7 @@ static void ui_menu_pubaddr_action_cancelled(void) { monero_io_do(IO_RETURN_AFTER_TX); } G_monero_vstate.disp_addr_mode = 0; - nbgl_useCaseStatus("Address display\ncancelled", false, ui_menu_main_display); + nbgl_useCaseReviewStatus(STATUS_TYPE_ADDRESS_REJECTED, ui_menu_main_display); } void ui_menu_pubaddr_action(bool confirm) { @@ -325,7 +325,7 @@ void ui_menu_pubaddr_action(bool confirm) { monero_io_do(IO_RETURN_AFTER_TX); } G_monero_vstate.disp_addr_mode = 0; - nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, ui_menu_main_display); + nbgl_useCaseReviewStatus(STATUS_TYPE_ADDRESS_VERIFIED, ui_menu_main_display); } else { ui_menu_pubaddr_action_cancelled(); } @@ -372,8 +372,8 @@ void display_account(void) { transactionContext.tagValueList.pairs = transactionContext.tagValuePair; - nbgl_useCaseAddressConfirmationExt(G_monero_vstate.ux_address, ui_menu_pubaddr_action, - &transactionContext.tagValueList); + nbgl_useCaseAddressReview(G_monero_vstate.ux_address, &transactionContext.tagValueList, + &C_Monero_64px, "Review Address", NULL, ui_menu_pubaddr_action); } int ui_menu_any_pubaddr_display(unsigned int value __attribute__((unused)), unsigned char* pub_view, @@ -388,8 +388,8 @@ int ui_menu_any_pubaddr_display(unsigned int value __attribute__((unused)), unsi return error; } - nbgl_useCaseReviewStart(&C_Monero_64px, "Review Address", "", "Cancel", display_account, - ui_menu_pubaddr_action_cancelled); + display_account(); + return 0; } diff --git a/src/monero_ux_stax_menu.c b/src/monero_ux_nbgl_menu.c similarity index 87% rename from src/monero_ux_stax_menu.c rename to src/monero_ux_nbgl_menu.c index fa1b8bc..259b705 100644 --- a/src/monero_ux_stax_menu.c +++ b/src/monero_ux_nbgl_menu.c @@ -56,6 +56,7 @@ enum { RESET_TOKEN, ACCOUNT_CHOICE, ACCOUNT_CHOICE_2, + ACCOUNT_CHOICE_3, NETWORK_CHOICE }; @@ -63,7 +64,7 @@ enum { MAIN_NET, STAGE_NET, TEST_NET, MAX_NET }; static const char* const infoTypes[] = {"Spec", "Version", "Developer", "Copyright"}; static const char* const infoContents[] = {XSTR(SPEC_VERSION), APPVERSION, "Ledger", - "(c) 2022 Ledger"}; + "(c) 2024 Ledger"}; static const char* const barTexts[] = {"Select Account", "Select Network", "Reset"}; static const uint8_t tokens[] = {ACCOUNT_TOKEN, NETWORK_TOKEN, RESET_TOKEN}; @@ -92,14 +93,14 @@ static bool settings_navigation_cb(uint8_t page, nbgl_pageContent_t* content) { content->barsList.tuneId = TUNE_TAP_CASUAL; } else if (page == 1) { content->type = INFOS_LIST; - content->infosList.nbInfos = 3; + content->infosList.nbInfos = 2; content->infosList.infoTypes = infoTypes; content->infosList.infoContents = infoContents; } else if (page == 2) { content->type = INFOS_LIST; - content->infosList.nbInfos = 1; - content->infosList.infoTypes = infoTypes + 3; - content->infosList.infoContents = infoContents + 3; + content->infosList.nbInfos = 2; + content->infosList.infoTypes = infoTypes + 2; + content->infosList.infoContents = infoContents + 2; } else { return false; } @@ -108,7 +109,7 @@ static bool settings_navigation_cb(uint8_t page, nbgl_pageContent_t* content) { static bool account_settings_navigation_cb(uint8_t page, nbgl_pageContent_t* content) { content->type = CHOICES_LIST; - content->choicesList.nbChoices = 5; + content->choicesList.nbChoices = 4; content->choicesList.localized = false; content->choicesList.tuneId = TUNE_TAP_CASUAL; @@ -117,13 +118,22 @@ static bool account_settings_navigation_cb(uint8_t page, nbgl_pageContent_t* con content->choicesList.names = accountNames; content->choicesList.token = ACCOUNT_CHOICE; } else if (page == 1) { - if (N_monero_pstate->account_id > 4) { - content->choicesList.initChoice = N_monero_pstate->account_id - 5; + if (N_monero_pstate->account_id > 3) { + content->choicesList.initChoice = N_monero_pstate->account_id - 4; } else { - content->choicesList.initChoice = 5; + content->choicesList.initChoice = 4; } - content->choicesList.names = accountNames + 5; + content->choicesList.names = accountNames + 4; content->choicesList.token = ACCOUNT_CHOICE_2; + } else if (page == 2) { + content->choicesList.nbChoices = 2; + if (N_monero_pstate->account_id > 7) { + content->choicesList.initChoice = N_monero_pstate->account_id - 8; + } else { + content->choicesList.initChoice = 8; + } + content->choicesList.names = accountNames + 8; + content->choicesList.token = ACCOUNT_CHOICE_3; } else { return false; } @@ -166,8 +176,11 @@ static void resetCallback(void) { static void account_settings_control_cb(int token, uint8_t index) { UNUSED(index); switch (token) { + case ACCOUNT_CHOICE_3: + index = index + 4; + __attribute__((fallthrough)); case ACCOUNT_CHOICE_2: - index = index + 5; + index = index + 4; __attribute__((fallthrough)); case ACCOUNT_CHOICE: if (index <= 9) { @@ -213,7 +226,7 @@ static void settings_control_cb(int token, uint8_t index) { UNUSED(index); switch (token) { case ACCOUNT_TOKEN: - nbgl_useCaseSettings("Select account", 0, 2, IS_TOUCHABLE, display_settings_menu, + nbgl_useCaseSettings("Select account", 0, 3, IS_TOUCHABLE, display_settings_menu, account_settings_navigation_cb, account_settings_control_cb); break; case NETWORK_TOKEN: @@ -232,7 +245,7 @@ static void settings_control_cb(int token, uint8_t index) { } static void display_settings_menu(void) { - nbgl_useCaseSettings("Monero settings", PAGE_START, NB_PAGE_SETTING, IS_TOUCHABLE, + nbgl_useCaseSettings("Monero", PAGE_START, NB_PAGE_SETTING, IS_TOUCHABLE, ui_menu_main_display, settings_navigation_cb, settings_control_cb); } diff --git a/src/monero_vars.h b/src/monero_vars.h index d46166e..547d41a 100644 --- a/src/monero_vars.h +++ b/src/monero_vars.h @@ -28,7 +28,7 @@ extern monero_v_state_t G_monero_vstate; -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) +#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) || defined(TARGET_FLEX) extern const monero_nv_state_t N_state_pic; #define N_monero_pstate ((volatile monero_nv_state_t *)PIC(&N_state_pic)) #else diff --git a/tests/monero_client/monero_cmd.py b/tests/monero_client/monero_cmd.py index e494379..4c2592b 100644 --- a/tests/monero_client/monero_cmd.py +++ b/tests/monero_client/monero_cmd.py @@ -229,16 +229,14 @@ def prefix_hash_init(self, backend, test_name, firmware, navigator, version: int instructions = get_nano_review_instructions(1) else: instructions = [ - NavIns(NavInsID.USE_CASE_REVIEW_TAP) + NavIns(NavInsID.SWIPE_CENTER_TO_LEFT) ] - with self.device.send_async(cla=PROTOCOL_VERSION, ins=ins, p1=1, p2=0, option=0, payload=payload): - navigator.navigate_and_compare(TESTS_ROOT_DIR, test_name + "_hash_init", instructions) @@ -458,7 +456,8 @@ def validate_prehash_update(self, instructions = get_nano_review_instructions(3) else: instructions = [ - NavIns(NavInsID.USE_CASE_REVIEW_TAP), + + NavIns(NavInsID.SWIPE_CENTER_TO_LEFT), NavIns(NavInsID.USE_CASE_REVIEW_TAP), NavIns(NavInsID.USE_CASE_REVIEW_CONFIRM) ] @@ -474,8 +473,8 @@ def validate_prehash_update(self, navigator.navigate_and_compare(TESTS_ROOT_DIR, test_name + "_prehash_update", - instructions, - screen_change_after_last_instruction=False) + instructions, + screen_change_after_last_instruction=False, timeout=10000) sw, response = self.device.async_response() # type: int, bytes diff --git a/tests/monero_client/monero_crypto_cmd.py b/tests/monero_client/monero_crypto_cmd.py index 8a8c56c..2066a7b 100644 --- a/tests/monero_client/monero_crypto_cmd.py +++ b/tests/monero_client/monero_crypto_cmd.py @@ -120,14 +120,13 @@ def display_address(self, test_name, firmware, navigator, derivation: bytes, out instructions = get_nano_review_instructions(4) else: instructions = [ - NavIns(NavInsID.USE_CASE_CHOICE_CONFIRM), - NavIns(NavInsID.TOUCH, (200, 410)), + NavIns(NavInsID.SWIPE_CENTER_TO_LEFT), + NavIns(NavInsID.TOUCH, (200, 350 if firmware.device.startswith("flex") else 410)), NavIns(NavInsID.USE_CASE_ADDRESS_CONFIRMATION_EXIT_QR), - NavIns(NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP), + NavIns(NavInsID.SWIPE_CENTER_TO_LEFT), NavIns(NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM), NavIns(NavInsID.USE_CASE_STATUS_DISMISS) ] - with self.device.send_async(cla=PROTOCOL_VERSION, ins=ins, p1=0, diff --git a/tests/snapshots/flex/test_display_address/00000.png b/tests/snapshots/flex/test_display_address/00000.png new file mode 100644 index 0000000..18c1600 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00000.png differ diff --git a/tests/snapshots/flex/test_display_address/00001.png b/tests/snapshots/flex/test_display_address/00001.png new file mode 100644 index 0000000..075ca11 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00001.png differ diff --git a/tests/snapshots/flex/test_display_address/00002.png b/tests/snapshots/flex/test_display_address/00002.png new file mode 100644 index 0000000..85e2829 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00002.png differ diff --git a/tests/snapshots/flex/test_display_address/00003.png b/tests/snapshots/flex/test_display_address/00003.png new file mode 100644 index 0000000..075ca11 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00003.png differ diff --git a/tests/snapshots/flex/test_display_address/00004.png b/tests/snapshots/flex/test_display_address/00004.png new file mode 100644 index 0000000..27b70e0 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00004.png differ diff --git a/tests/snapshots/flex/test_display_address/00005.png b/tests/snapshots/flex/test_display_address/00005.png new file mode 100644 index 0000000..4321e60 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00005.png differ diff --git a/tests/snapshots/flex/test_display_address/00006.png b/tests/snapshots/flex/test_display_address/00006.png new file mode 100644 index 0000000..876e018 Binary files /dev/null and b/tests/snapshots/flex/test_display_address/00006.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00000.png b/tests/snapshots/flex/test_display_subaddress/00000.png new file mode 100644 index 0000000..18c1600 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00000.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00001.png b/tests/snapshots/flex/test_display_subaddress/00001.png new file mode 100644 index 0000000..f9bc649 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00001.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00002.png b/tests/snapshots/flex/test_display_subaddress/00002.png new file mode 100644 index 0000000..ef596e6 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00002.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00003.png b/tests/snapshots/flex/test_display_subaddress/00003.png new file mode 100644 index 0000000..f9bc649 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00003.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00004.png b/tests/snapshots/flex/test_display_subaddress/00004.png new file mode 100644 index 0000000..409120c Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00004.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00005.png b/tests/snapshots/flex/test_display_subaddress/00005.png new file mode 100644 index 0000000..4321e60 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00005.png differ diff --git a/tests/snapshots/flex/test_display_subaddress/00006.png b/tests/snapshots/flex/test_display_subaddress/00006.png new file mode 100644 index 0000000..876e018 Binary files /dev/null and b/tests/snapshots/flex/test_display_subaddress/00006.png differ diff --git a/tests/snapshots/flex/test_prefix_hash_hash_init/00000.png b/tests/snapshots/flex/test_prefix_hash_hash_init/00000.png new file mode 100644 index 0000000..60911ae Binary files /dev/null and b/tests/snapshots/flex/test_prefix_hash_hash_init/00000.png differ diff --git a/tests/snapshots/flex/test_prefix_hash_hash_init/00001.png b/tests/snapshots/flex/test_prefix_hash_hash_init/00001.png new file mode 100644 index 0000000..92bcce3 Binary files /dev/null and b/tests/snapshots/flex/test_prefix_hash_hash_init/00001.png differ diff --git a/tests/snapshots/flex/test_private_view_key/00000.png b/tests/snapshots/flex/test_private_view_key/00000.png new file mode 100644 index 0000000..146a5f5 Binary files /dev/null and b/tests/snapshots/flex/test_private_view_key/00000.png differ diff --git a/tests/snapshots/flex/test_private_view_key/00001.png b/tests/snapshots/flex/test_private_view_key/00001.png new file mode 100644 index 0000000..d08de44 Binary files /dev/null and b/tests/snapshots/flex/test_private_view_key/00001.png differ diff --git a/tests/snapshots/flex/test_validate_prehash_update/00000.png b/tests/snapshots/flex/test_validate_prehash_update/00000.png new file mode 100644 index 0000000..3b2829c Binary files /dev/null and b/tests/snapshots/flex/test_validate_prehash_update/00000.png differ diff --git a/tests/snapshots/flex/test_validate_prehash_update/00001.png b/tests/snapshots/flex/test_validate_prehash_update/00001.png new file mode 100644 index 0000000..daf5fa5 Binary files /dev/null and b/tests/snapshots/flex/test_validate_prehash_update/00001.png differ diff --git a/tests/snapshots/flex/test_validate_prehash_update/00002.png b/tests/snapshots/flex/test_validate_prehash_update/00002.png new file mode 100644 index 0000000..7ff7fa9 Binary files /dev/null and b/tests/snapshots/flex/test_validate_prehash_update/00002.png differ diff --git a/tests/snapshots/stax/test_display_address/00000.png b/tests/snapshots/stax/test_display_address/00000.png index 153d298..9cc0861 100644 Binary files a/tests/snapshots/stax/test_display_address/00000.png and b/tests/snapshots/stax/test_display_address/00000.png differ diff --git a/tests/snapshots/stax/test_display_address/00001.png b/tests/snapshots/stax/test_display_address/00001.png index a793ded..b331e02 100644 Binary files a/tests/snapshots/stax/test_display_address/00001.png and b/tests/snapshots/stax/test_display_address/00001.png differ diff --git a/tests/snapshots/stax/test_display_address/00003.png b/tests/snapshots/stax/test_display_address/00003.png index a793ded..b331e02 100644 Binary files a/tests/snapshots/stax/test_display_address/00003.png and b/tests/snapshots/stax/test_display_address/00003.png differ diff --git a/tests/snapshots/stax/test_display_address/00004.png b/tests/snapshots/stax/test_display_address/00004.png index 1d12a31..3a3a98e 100644 Binary files a/tests/snapshots/stax/test_display_address/00004.png and b/tests/snapshots/stax/test_display_address/00004.png differ diff --git a/tests/snapshots/stax/test_display_address/00005.png b/tests/snapshots/stax/test_display_address/00005.png index 13499fc..3f906b2 100644 Binary files a/tests/snapshots/stax/test_display_address/00005.png and b/tests/snapshots/stax/test_display_address/00005.png differ diff --git a/tests/snapshots/stax/test_display_subaddress/00000.png b/tests/snapshots/stax/test_display_subaddress/00000.png index 153d298..9cc0861 100644 Binary files a/tests/snapshots/stax/test_display_subaddress/00000.png and b/tests/snapshots/stax/test_display_subaddress/00000.png differ diff --git a/tests/snapshots/stax/test_display_subaddress/00001.png b/tests/snapshots/stax/test_display_subaddress/00001.png index 5066062..e6bce05 100644 Binary files a/tests/snapshots/stax/test_display_subaddress/00001.png and b/tests/snapshots/stax/test_display_subaddress/00001.png differ diff --git a/tests/snapshots/stax/test_display_subaddress/00003.png b/tests/snapshots/stax/test_display_subaddress/00003.png index 5066062..e6bce05 100644 Binary files a/tests/snapshots/stax/test_display_subaddress/00003.png and b/tests/snapshots/stax/test_display_subaddress/00003.png differ diff --git a/tests/snapshots/stax/test_display_subaddress/00004.png b/tests/snapshots/stax/test_display_subaddress/00004.png index 4ca0934..58f51b5 100644 Binary files a/tests/snapshots/stax/test_display_subaddress/00004.png and b/tests/snapshots/stax/test_display_subaddress/00004.png differ diff --git a/tests/snapshots/stax/test_display_subaddress/00005.png b/tests/snapshots/stax/test_display_subaddress/00005.png index 13499fc..3f906b2 100644 Binary files a/tests/snapshots/stax/test_display_subaddress/00005.png and b/tests/snapshots/stax/test_display_subaddress/00005.png differ diff --git a/tests/test_version.py b/tests/test_version.py index e17d544..fc4c644 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -8,7 +8,7 @@ def check_accepted_version(monero, valid_version: bytes): major, minor, patch = monero.reset_and_get_version( monero_client_version=valid_version ) # type: int, int, int - assert (major, minor, patch) == (1, 9, 0) # version of the Monero app + assert (major, minor, patch) == (2, 0, 0) # version of the Monero app def check_refused_version(monero, invalid_version: bytes):