diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index acca4c1..6d515ee 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -25,7 +25,7 @@ jobs: artifact: aptos-app-nanosp runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:bd1db4121a88260b9b6866d3c05b7d20f928743b steps: - name: Clone @@ -46,7 +46,7 @@ jobs: name: Clang Static Analyzer runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:bd1db4121a88260b9b6866d3c05b7d20f928743b steps: - name: Clone @@ -68,7 +68,7 @@ jobs: name: Unit test runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:bd1db4121a88260b9b6866d3c05b7d20f928743b steps: - name: Install curl @@ -108,7 +108,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:bd1db4121a88260b9b6866d3c05b7d20f928743b steps: - name: Clone diff --git a/Makefile b/Makefile index 92d9fb1..013475f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # **************************************************************************** -# Ledger App Boilerplate +# Ledger App Aptos # (c) 2020 Ledger SAS. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,8 +32,8 @@ APP_LOAD_PARAMS += $(COMMON_LOAD_PARAMS) APPNAME = "Aptos" APPVERSION_M = 0 -APPVERSION_N = 1 -APPVERSION_P = 0 +APPVERSION_N = 3 +APPVERSION_P = 4 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" ifeq ($(TARGET_NAME),TARGET_NANOS) @@ -56,6 +56,16 @@ DEFINES += BLE_SEGMENT_SIZE=32 DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" DEFINES += UNUSED\(x\)=\(void\)x +ifeq ($(TARGET_NAME),TARGET_NANOS) + DEFINES += MAX_TRANSACTION_PACKETS=6 +endif +ifeq ($(TARGET_NAME),TARGET_NANOS2) + DEFINES += MAX_TRANSACTION_PACKETS=106 +endif +ifeq ($(TARGET_NAME),TARGET_NANOX) + DEFINES += MAX_TRANSACTION_PACKETS=104 +endif + ifeq ($(TARGET_NAME),TARGET_NANOX) DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU endif diff --git a/fuzzing/fuzz_tx_parser.cc b/fuzzing/fuzz_tx_parser.cc index b653c8d..df4bf5c 100644 --- a/fuzzing/fuzz_tx_parser.cc +++ b/fuzzing/fuzz_tx_parser.cc @@ -21,7 +21,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { transaction_init(&tx); status = transaction_deserialize(&buf, &tx); - if (status == PARSING_OK && tx.tx_variant == TX_RAW) { + if (status == PARSING_OK && tx.tx_variant == TX_RAW && + tx.payload_variant == PAYLOAD_ENTRY_FUNCTION) { printf("\nTransaction size: %lu\n", size); printf("chain_id: %d\n", tx.chain_id); printf("sequence: %lu\n", tx.sequence); @@ -31,6 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { format_hex(tx.sender, ADDRESS_LEN, sender, sizeof(sender)); printf("sender: %s\n", sender); printf("payload_variant: %d\n", tx.payload_variant); + printf("entry_function.known_type: %d\n", tx.payload.entry_function.known_type); } return 0; diff --git a/src/address.c b/src/address.c index a706476..e74baa1 100644 --- a/src/address.c +++ b/src/address.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/apdu/dispatcher.c b/src/apdu/dispatcher.c index 2f20967..934cbbc 100644 --- a/src/apdu/dispatcher.c +++ b/src/apdu/dispatcher.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/apdu/dispatcher.h b/src/apdu/dispatcher.h index 9b9c001..2847bb2 100644 --- a/src/apdu/dispatcher.h +++ b/src/apdu/dispatcher.h @@ -17,7 +17,7 @@ /** * Parameter 1 for maximum APDU number. */ -#define P1_MAX 0x03 +#define P1_MAX (MAX_TRANSACTION_PACKETS + 1) /** * Dispatch APDU command received to the right handler. diff --git a/src/apdu/parser.c b/src/apdu/parser.c index cbf4336..fad86ef 100644 --- a/src/apdu/parser.c +++ b/src/apdu/parser.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/constants.h b/src/constants.h index 67ddb67..9e81169 100644 --- a/src/constants.h +++ b/src/constants.h @@ -20,10 +20,17 @@ */ #define MAX_APPNAME_LEN 64 +/** + * Maximum transaction packets. + */ +#ifndef MAX_TRANSACTION_PACKETS +#define MAX_TRANSACTION_PACKETS 2 +#endif + /** * Maximum transaction length (bytes). */ -#define MAX_TRANSACTION_LEN 510 +#define MAX_TRANSACTION_LEN (MAX_TRANSACTION_PACKETS * 255) /** * Signature length (bytes). diff --git a/src/crypto.c b/src/crypto.c index 3a9153b..47a68b8 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/globals.h b/src/globals.h index a158c35..3ca735e 100644 --- a/src/globals.h +++ b/src/globals.h @@ -27,3 +27,9 @@ extern bolos_ux_params_t G_ux_params; * Global context for user requests. */ extern global_ctx_t G_context; + +/** + * Global NVM app storage. + */ +extern const app_storage_t N_app_storage; +#define N_storage (*(volatile app_storage_t*) PIC(&N_app_storage)) diff --git a/src/handler/get_app_name.c b/src/handler/get_app_name.c index 50276a1..95383aa 100644 --- a/src/handler/get_app_name.c +++ b/src/handler/get_app_name.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/handler/get_public_key.c b/src/handler/get_public_key.c index 61d8066..b873742 100644 --- a/src/handler/get_public_key.c +++ b/src/handler/get_public_key.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/handler/get_version.c b/src/handler/get_version.c index e32a5e2..cb9700a 100644 --- a/src/handler/get_version.c +++ b/src/handler/get_version.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/handler/sign_tx.c b/src/handler/sign_tx.c index 4fd569c..0c120c3 100644 --- a/src/handler/sign_tx.c +++ b/src/handler/sign_tx.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/helper/send_reponse.c b/src/helper/send_reponse.c index 0353996..df0d9af 100644 --- a/src/helper/send_reponse.c +++ b/src/helper/send_reponse.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/io.c b/src/io.c index 2dc6702..4f54c78 100644 --- a/src/io.c +++ b/src/io.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/main.c b/src/main.c index 9b46720..a6dbeb9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,7 @@ uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; ux_state_t G_ux; bolos_ux_params_t G_ux_params; global_ctx_t G_context; +const app_storage_t N_app_storage; /** * Handle APDU command received and send back APDU response using handlers. @@ -110,6 +111,15 @@ void app_exit() { END_TRY_L(exit); } +void nvm_app_storage_init() { + if (N_storage.initialized != 0x01) { + app_storage_t storage; + storage.settings.show_full_message = 0x00; + storage.initialized = 0x01; + nvm_write((void *) &N_storage, (void *) &storage, sizeof(app_storage_t)); + } +} + /** * Main loop to setup USB, Bluetooth, UI and launch app_main(). */ @@ -125,6 +135,7 @@ __attribute__((section(".boot"))) int main() { BEGIN_TRY { TRY { io_seproxyhal_init(); + nvm_app_storage_init(); #ifdef TARGET_NANOX G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); diff --git a/src/transaction/deserialize.c b/src/transaction/deserialize.c index c5170e6..315e90a 100644 --- a/src/transaction/deserialize.c +++ b/src/transaction/deserialize.c @@ -95,6 +95,7 @@ parser_status_e tx_raw_deserialize(buffer_t *buf, transaction_t *tx) { } parser_status_e tx_variant_deserialize(buffer_t *buf, transaction_t *tx) { + parser_status_e status = TX_VARIANT_UNDEFINED_ERROR; if (buf->offset != 0) { return TX_VARIANT_READ_ERROR; } @@ -103,18 +104,18 @@ parser_status_e tx_variant_deserialize(buffer_t *buf, transaction_t *tx) { uint8_t *prefix; // read hashed prefix bytes - if (!bcs_read_ptr_to_fixed_bytes(buf, &prefix, TX_HASHED_PREFIX_LEN)) { - return HASHED_PREFIX_READ_ERROR; - } - - if (memcmp(prefix, PREFIX_RAW_TX_WITH_DATA_HASHED, TX_HASHED_PREFIX_LEN) == 0) { - tx->tx_variant = TX_RAW_WITH_DATA; - return PARSING_OK; - } + if (bcs_read_ptr_to_fixed_bytes(buf, &prefix, TX_HASHED_PREFIX_LEN)) { + if (memcmp(prefix, PREFIX_RAW_TX_WITH_DATA_HASHED, TX_HASHED_PREFIX_LEN) == 0) { + tx->tx_variant = TX_RAW_WITH_DATA; + return PARSING_OK; + } - if (memcmp(prefix, PREFIX_RAW_TX_HASHED, TX_HASHED_PREFIX_LEN) == 0) { - tx->tx_variant = TX_RAW; - return PARSING_OK; + if (memcmp(prefix, PREFIX_RAW_TX_HASHED, TX_HASHED_PREFIX_LEN) == 0) { + tx->tx_variant = TX_RAW; + return PARSING_OK; + } + } else { + status = HASHED_PREFIX_READ_ERROR; } if (transaction_utils_check_encoding(buf->ptr, buf->size)) { @@ -123,7 +124,7 @@ parser_status_e tx_variant_deserialize(buffer_t *buf, transaction_t *tx) { return PARSING_OK; } - return TX_VARIANT_UNDEFINED_ERROR; + return status; } parser_status_e entry_function_payload_deserialize(buffer_t *buf, transaction_t *tx) { @@ -323,17 +324,15 @@ entry_function_known_type_t determine_function_type(transaction_t *tx) { return FUNC_UNKNOWN; } - // TODO: Add string length check before comparison if (tx->payload.entry_function.module_id.address[ADDRESS_LEN - 1] == 0x01 && - memcmp(tx->payload.entry_function.module_id.name.bytes, "aptos_account", 13) == 0 && - memcmp(tx->payload.entry_function.function_name.bytes, "transfer", 8) == 0) { + bcs_cmp_bytes(&tx->payload.entry_function.module_id.name, "aptos_account", 13) && + bcs_cmp_bytes(&tx->payload.entry_function.function_name, "transfer", 8)) { return FUNC_APTOS_ACCOUNT_TRANSFER; } - // TODO: Add string length check before comparison if (tx->payload.entry_function.module_id.address[ADDRESS_LEN - 1] == 0x01 && - memcmp(tx->payload.entry_function.module_id.name.bytes, "coin", 4) == 0 && - memcmp(tx->payload.entry_function.function_name.bytes, "transfer", 8) == 0) { + bcs_cmp_bytes(&tx->payload.entry_function.module_id.name, "coin", 4) && + bcs_cmp_bytes(&tx->payload.entry_function.function_name, "transfer", 8)) { return FUNC_COIN_TRANSFER; } diff --git a/src/transaction/utils.c b/src/transaction/utils.c index 565d539..33f08a1 100644 --- a/src/transaction/utils.c +++ b/src/transaction/utils.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +17,7 @@ #include // uint*_t #include // bool -#include // memmove +#include // memcmp #include "types.h" @@ -30,3 +30,7 @@ bool transaction_utils_check_encoding(const uint8_t *msg, uint64_t msg_len) { return true; } + +bool bcs_cmp_bytes(const fixed_bytes_t *bcs_bytes, const void *value, size_t len) { + return bcs_bytes->len == len && memcmp(bcs_bytes->bytes, value, len) == 0; +} diff --git a/src/transaction/utils.h b/src/transaction/utils.h index d1c63bf..5c8ad8f 100644 --- a/src/transaction/utils.h +++ b/src/transaction/utils.h @@ -17,3 +17,18 @@ * */ bool transaction_utils_check_encoding(const uint8_t *msg, uint64_t msg_len); + +/** + * Compares the fixed_bytes_t bcs_bytes to the memory pointed by value. + * + * @param[in] bcs_bytes + * Pointer to fixed_bytes_t struct. + * @param[in] value + * Pointer to input block of memory. + * @param[in] len + * Length of input bytes to compare. + * + * @return true if success, false otherwise. + * + */ +bool bcs_cmp_bytes(const fixed_bytes_t *bcs_bytes, const void *value, size_t len); diff --git a/src/types.h b/src/types.h index 830762f..da1743b 100644 --- a/src/types.h +++ b/src/types.h @@ -88,3 +88,12 @@ typedef struct { uint32_t bip32_path[MAX_BIP32_PATH]; /// BIP32 path uint8_t bip32_path_len; /// length of BIP32 path } global_ctx_t; + +typedef struct { + uint8_t show_full_message; +} app_settings; + +typedef struct { + app_settings settings; + uint8_t initialized; +} app_storage_t; diff --git a/src/ui/action/validate.c b/src/ui/action/validate.c index b6f65f7..8565842 100644 --- a/src/ui/action/validate.c +++ b/src/ui/action/validate.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/ui/display.c b/src/ui/display.c index 2363f4a..361174d 100644 --- a/src/ui/display.c +++ b/src/ui/display.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,13 +36,15 @@ #include "../common/bip32.h" #include "../common/format.h" +#define DOTS "[...]" + static action_validate_cb g_validate_callback; static char g_amount[30]; static char g_gas_fee[30]; static char g_bip32_path[60]; static char g_address[67]; static char g_function[50]; -static char g_struct[250]; +static char g_struct[120]; // Step with icon and text UX_STEP_NOCB(ux_display_confirm_addr_step, pn, {&C_icon_eye, "Confirm Address"}); @@ -136,6 +138,13 @@ UX_STEP_NOCB(ux_display_review_msg_step, }); // Step with title/text for message UX_STEP_NOCB(ux_display_msg_step, + bnnn_paging, + { + .title = "Message", + .text = (const char *) G_context.tx_info.raw_tx, + }); +// Step with title/text for message in short form +UX_STEP_NOCB(ux_display_short_msg_step, bnnn_paging, { .title = "Message", @@ -208,6 +217,17 @@ UX_FLOW(ux_display_message_flow, &ux_display_approve_step, &ux_display_reject_step); +// FLOW to display message information in short form: +// #1 screen : eye icon + "Review Message" +// #2 screen : display message +// #3 screen : approve button +// #4 screen : reject button +UX_FLOW(ux_display_short_message_flow, + &ux_display_review_msg_step, + &ux_display_short_msg_step, + &ux_display_approve_step, + &ux_display_reject_step); + // FLOW to display entry_function transaction information: // #1 screen : eye icon + "Review Transaction" // #2 screen : display function name @@ -310,15 +330,20 @@ int ui_display_transaction() { } int ui_display_message() { - memset(g_struct, 0, sizeof(g_struct)); - snprintf(g_struct, - sizeof(g_struct), - "%.*s", - G_context.tx_info.raw_tx_len, - G_context.tx_info.raw_tx); - PRINTF("Message: %s\n", g_struct); - - ux_flow_init(0, ux_display_message_flow, NULL); + if (N_storage.settings.show_full_message) { + ux_flow_init(0, ux_display_message_flow, NULL); + } else { + memset(g_struct, 0, sizeof(g_struct)); + bool short_enough = G_context.tx_info.raw_tx_len < sizeof(g_struct); + snprintf(g_struct, + sizeof(g_struct), + short_enough ? "%.*s" : "%.*s" DOTS, + short_enough ? G_context.tx_info.raw_tx_len : sizeof(g_struct) - sizeof(DOTS), + G_context.tx_info.raw_tx); + PRINTF("Message: %s\n", g_struct); + + ux_flow_init(0, ux_display_short_message_flow, NULL); + } return 0; } diff --git a/src/ui/menu.c b/src/ui/menu.c index a393040..8583f84 100644 --- a/src/ui/menu.c +++ b/src/ui/menu.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Ledger App Boilerplate. + * Ledger App Aptos. * (c) 2020 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,20 +21,21 @@ #include "../globals.h" #include "menu.h" +#include "settings.h" UX_STEP_NOCB(ux_menu_ready_step, pnn, {&C_aptos_logo, "Aptos", "is ready"}); -UX_STEP_NOCB(ux_menu_version_step, bn, {"Version", APPVERSION}); +UX_STEP_CB(ux_menu_settings_step, pb, ui_menu_settings(), {&C_icon_coggle, "Settings"}); UX_STEP_CB(ux_menu_about_step, pb, ui_menu_about(), {&C_icon_certificate, "About"}); UX_STEP_VALID(ux_menu_exit_step, pb, os_sched_exit(-1), {&C_icon_dashboard_x, "Quit"}); // FLOW for the main menu: // #1 screen: ready -// #2 screen: version of the app +// #2 screen: settings // #3 screen: about submenu // #4 screen: quit UX_FLOW(ux_menu_main_flow, &ux_menu_ready_step, - &ux_menu_version_step, + &ux_menu_settings_step, &ux_menu_about_step, &ux_menu_exit_step, FLOW_LOOP); @@ -47,13 +48,23 @@ void ui_menu_main() { ux_flow_init(0, ux_menu_main_flow, NULL); } +void ui_menu_settings() { + ux_menulist_init(0, settings_submenu_getter, settings_submenu_selector); +} + UX_STEP_NOCB(ux_menu_info_step, bn, {"Aptos App", "(c) 2022 Pontem"}); +UX_STEP_NOCB(ux_menu_version_step, bn, {"Version", APPVERSION}); UX_STEP_CB(ux_menu_back_step, pb, ui_menu_main(), {&C_icon_back, "Back"}); // FLOW for the about submenu: // #1 screen: app info -// #2 screen: back button to main menu -UX_FLOW(ux_menu_about_flow, &ux_menu_info_step, &ux_menu_back_step, FLOW_LOOP); +// #2 screen: version of the app +// #3 screen: back button to main menu +UX_FLOW(ux_menu_about_flow, + &ux_menu_info_step, + &ux_menu_version_step, + &ux_menu_back_step, + FLOW_LOOP); void ui_menu_about() { ux_flow_init(0, ux_menu_about_flow, NULL); diff --git a/src/ui/menu.h b/src/ui/menu.h index d9c69e0..1a4c6e2 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -1,10 +1,15 @@ #pragma once /** - * Show main menu (ready screen, version, about, quit). + * Show main menu (ready screen, settings, version, about, quit). */ void ui_menu_main(void); +/** + * Show settings submenu (show_full_message). + */ +void ui_menu_settings(void); + /** * Show about submenu (copyright, date). */ diff --git a/src/ui/settings.c b/src/ui/settings.c new file mode 100644 index 0000000..e43c2ca --- /dev/null +++ b/src/ui/settings.c @@ -0,0 +1,53 @@ +#include "os.h" + +#include "settings.h" +#include "menu.h" +#include "../globals.h" + +static const char* const show_full_message_getter_values[] = {"No", "Yes", "Back"}; + +static const char* show_full_message_getter(unsigned int idx) { + if (idx < ARRAYLEN(show_full_message_getter_values)) { + return show_full_message_getter_values[idx]; + } + return NULL; +} + +static void show_full_message_change(uint8_t value) { + nvm_write((void*) &N_storage.settings.show_full_message, &value, sizeof(value)); +} + +static void show_full_message_selector(unsigned int idx) { + if (idx == 0 || idx == 1) { + show_full_message_change((uint8_t) idx); + } + ux_menulist_init_select(0, + settings_submenu_getter, + settings_submenu_selector, + MENU_SHOW_FULL_MSG); +} + +static const char* const settings_submenu_getter_values[] = { + "Show Full Message", + "Back", +}; + +const char* settings_submenu_getter(unsigned int idx) { + if (idx < ARRAYLEN(settings_submenu_getter_values)) { + return settings_submenu_getter_values[idx]; + } + return NULL; +} + +void settings_submenu_selector(unsigned int idx) { + switch (idx) { + case MENU_SHOW_FULL_MSG: + ux_menulist_init_select(0, + show_full_message_getter, + show_full_message_selector, + N_storage.settings.show_full_message); + break; + default: + ui_menu_main(); + } +} diff --git a/src/ui/settings.h b/src/ui/settings.h new file mode 100644 index 0000000..eb63b36 --- /dev/null +++ b/src/ui/settings.h @@ -0,0 +1,7 @@ +#pragma once + +enum menu_options { MENU_SHOW_FULL_MSG = 0 }; + +const char* settings_submenu_getter(unsigned int idx); + +void settings_submenu_selector(unsigned int idx); diff --git a/tests/ledgercomm/test_name_version.py b/tests/ledgercomm/test_name_version.py index a4ee3c9..996b13a 100644 --- a/tests/ledgercomm/test_name_version.py +++ b/tests/ledgercomm/test_name_version.py @@ -4,4 +4,4 @@ def test_get_app_and_version(cmd, hid): app_name, version = cmd.get_app_and_version() assert app_name == "Aptos" - assert version == "0.1.0" + assert version == "0.3.4" diff --git a/tests/ledgercomm/test_version_cmd.py b/tests/ledgercomm/test_version_cmd.py index 4596445..76e74de 100644 --- a/tests/ledgercomm/test_version_cmd.py +++ b/tests/ledgercomm/test_version_cmd.py @@ -1,2 +1,2 @@ def test_version(cmd): - assert cmd.get_version() == (0, 1, 0) + assert cmd.get_version() == (0, 3, 4) diff --git a/tests/speculos/test_version_cmd.py b/tests/speculos/test_version_cmd.py index 4596445..76e74de 100644 --- a/tests/speculos/test_version_cmd.py +++ b/tests/speculos/test_version_cmd.py @@ -1,2 +1,2 @@ def test_version(cmd): - assert cmd.get_version() == (0, 1, 0) + assert cmd.get_version() == (0, 3, 4)