#include "shared_context.h" #include "ui_callbacks.h" #include "common_ui.h" #include "common_utils.h" #include "feature_signTx.h" #define ENABLED_STR "Enabled" #define DISABLED_STR "Disabled" #define BUF_INCREMENT (MAX(strlen(ENABLED_STR), strlen(DISABLED_STR)) + 1) // Reuse the strings.common.fullAmount buffer for settings displaying. // No risk of collision as this buffer is unused in the settings menu #define SETTING_VERBOSE_DOMAIN_NAME_STATE (strings.common.fullAmount + (BUF_INCREMENT * 0)) #define SETTING_VERBOSE_EIP712_STATE (strings.common.fullAmount + (BUF_INCREMENT * 1)) #define SETTING_DISPLAY_NONCE_STATE (strings.common.fullAmount + (BUF_INCREMENT * 2)) #define SETTING_DISPLAY_DATA_STATE (strings.common.fullAmount + (BUF_INCREMENT * 3)) #define BOOL_TO_STATE_STR(b) (b ? ENABLED_STR : DISABLED_STR) static void display_settings(const ux_flow_step_t* const start_step); static void switch_settings_display_data(void); static void switch_settings_display_nonce(void); #ifdef HAVE_EIP712_FULL_SUPPORT static void switch_settings_verbose_eip712(void); #endif // HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_DOMAIN_NAME static void switch_settings_verbose_domain_name(void); #endif // HAVE_DOMAIN_NAME ////////////////////////////////////////////////////////////////////// // clang-format off UX_STEP_NOCB( ux_idle_flow_1_step, nn, //pnn, { //"", //&C_icon_dashboard, "Application", "is ready", }); UX_STEP_NOCB( ux_idle_flow_2_step, bn, { "Version", APPVERSION, }); UX_STEP_CB( ux_idle_flow_3_step, pb, display_settings(NULL), { &C_icon_eye, "Settings", }); UX_STEP_CB( ux_idle_flow_4_step, pb, os_sched_exit(-1), { &C_icon_dashboard_x, "Quit", }); // clang-format on UX_FLOW(ux_idle_flow, &ux_idle_flow_1_step, &ux_idle_flow_2_step, &ux_idle_flow_3_step, &ux_idle_flow_4_step, FLOW_LOOP); // clang-format off #ifdef HAVE_DOMAIN_NAME UX_STEP_CB( ux_settings_flow_verbose_domain_name_step, bnnn, switch_settings_verbose_domain_name(), { "ENS addresses", "Displays resolved", "addresses from ENS", SETTING_VERBOSE_DOMAIN_NAME_STATE }); #endif // HAVE_DOMAIN_NAME #ifdef HAVE_EIP712_FULL_SUPPORT UX_STEP_CB( ux_settings_flow_verbose_eip712_step, bnnn, switch_settings_verbose_eip712(), { "Raw messages", "Displays raw content", "from EIP712 messages", SETTING_VERBOSE_EIP712_STATE }); #endif // HAVE_EIP712_FULL_SUPPORT UX_STEP_CB( ux_settings_flow_display_nonce_step, #ifdef TARGET_NANOS bnnn_paging, #else bnnn, #endif switch_settings_display_nonce(), { #ifdef TARGET_NANOS .title = "Account nonce", .text = #else "Nonce", "Displays nonce", "in transactions", #endif SETTING_DISPLAY_NONCE_STATE }); UX_STEP_CB( ux_settings_flow_display_data_step, #ifdef TARGET_NANOS bnnn_paging, #else bnnn, #endif switch_settings_display_data(), { #ifdef TARGET_NANOS .title = "Debug data", .text = #else "Debug contracts", "Displays contract", "data details", #endif SETTING_DISPLAY_DATA_STATE }); UX_STEP_CB( ux_settings_flow_back_step, pb, ui_idle(), { &C_icon_back_x, "Back", }); // clang-format on UX_FLOW(ux_settings_flow, #ifdef HAVE_DOMAIN_NAME &ux_settings_flow_verbose_domain_name_step, #endif // HAVE_DOMAIN_NAME #ifdef HAVE_EIP712_FULL_SUPPORT &ux_settings_flow_verbose_eip712_step, #endif // HAVE_EIP712_FULL_SUPPORT &ux_settings_flow_display_nonce_step, &ux_settings_flow_display_data_step, &ux_settings_flow_back_step); static void display_settings(const ux_flow_step_t* const start_step) { strlcpy(SETTING_DISPLAY_DATA_STATE, BOOL_TO_STATE_STR(N_storage.contractDetails), BUF_INCREMENT); strlcpy(SETTING_DISPLAY_NONCE_STATE, BOOL_TO_STATE_STR(N_storage.displayNonce), BUF_INCREMENT); #ifdef HAVE_EIP712_FULL_SUPPORT strlcpy(SETTING_VERBOSE_EIP712_STATE, BOOL_TO_STATE_STR(N_storage.verbose_eip712), BUF_INCREMENT); #endif // HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_DOMAIN_NAME strlcpy(SETTING_VERBOSE_DOMAIN_NAME_STATE, BOOL_TO_STATE_STR(N_storage.verbose_domain_name), BUF_INCREMENT); #endif // HAVE_DOMAIN_NAME ux_flow_init(0, ux_settings_flow, start_step); } static void toggle_setting(volatile bool* setting, const ux_flow_step_t* ui_step) { bool value = !*setting; nvm_write((void*) setting, (void*) &value, sizeof(value)); display_settings(ui_step); } static void switch_settings_display_data(void) { toggle_setting(&N_storage.contractDetails, &ux_settings_flow_display_data_step); } static void switch_settings_display_nonce(void) { toggle_setting(&N_storage.displayNonce, &ux_settings_flow_display_nonce_step); } #ifdef HAVE_EIP712_FULL_SUPPORT static void switch_settings_verbose_eip712(void) { toggle_setting(&N_storage.verbose_eip712, &ux_settings_flow_verbose_eip712_step); } #endif // HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_DOMAIN_NAME static void switch_settings_verbose_domain_name(void) { toggle_setting(&N_storage.verbose_domain_name, &ux_settings_flow_verbose_domain_name_step); } #endif // HAVE_DOMAIN_NAME ////////////////////////////////////////////////////////////////////// // clang-format off UX_STEP_NOCB( ux_blind_signing_warning_step, pbb, { &C_icon_warning, #ifdef TARGET_NANOS "Transaction", "not trusted", #else "This transaction", "cannot be trusted", #endif }); #ifndef TARGET_NANOS UX_STEP_NOCB( ux_blind_signing_text1_step, nnnn, { "Your Ledger cannot", "decode this", "transaction. If you", "sign it, you could", }); UX_STEP_NOCB( ux_blind_signing_text2_step, nnnn, { "be authorizing", "malicious actions", "that can drain your", "wallet.", }); #endif UX_STEP_NOCB( ux_blind_signing_link_step, nn, { "Learn more:", "ledger.com/e8", }); UX_STEP_CB( ux_blind_signing_accept_step, pbb, start_signature_flow(), { &C_icon_validate_14, #ifdef TARGET_NANOS "Accept risk", "and review", #else "Accept risk and", "review transaction", #endif }); UX_STEP_CB( ux_blind_signing_reject_step, pb, report_finalize_error(), { &C_icon_crossmark, "Reject", }); // clang-format on UX_FLOW(ux_blind_signing_flow, &ux_blind_signing_warning_step, #ifndef TARGET_NANOS &ux_blind_signing_text1_step, &ux_blind_signing_text2_step, #endif &ux_blind_signing_link_step, &ux_blind_signing_accept_step, &ux_blind_signing_reject_step);